0024001: Stereographic rendering support
[occt.git] / src / OpenGl / OpenGl_AspectMarker.cxx
1 // Created on: 2011-07-14
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and / or modify it
8 // under the terms of the GNU Lesser General Public version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <OpenGl_AspectMarker.hxx>
17 #include <OpenGl_Context.hxx>
18 #include <OpenGl_GraphicDriver.hxx>
19 #include <OpenGl_PointSprite.hxx>
20 #include <OpenGl_ShaderManager.hxx>
21 #include <OpenGl_ShaderProgram.hxx>
22 #include <OpenGl_Workspace.hxx>
23
24 #include <Image_PixMap.hxx>
25 #include <Graphic3d_MarkerImage.hxx>
26 #include <Graphic3d_ShaderProgram.hxx>
27 #include <NCollection_Vec4.hxx>
28 #include <TColStd_HArray1OfByte.hxx>
29
30 namespace
31 {
32   static const TEL_COLOUR myDefaultColor = {{ 1.0F, 1.0F, 1.0F, 1.0F }};
33   static const TCollection_AsciiString THE_EMPTY_KEY;
34 };
35
36 // Following Section relates to default markers
37
38 #define TEL_NO_OF_SIZES 13
39 #define TEL_PM_START_SIZE 1.0
40 #define TEL_PM_END_SIZE   7.0
41
42 struct PM_FONT_INFO
43 {
44   Tfloat width, height;
45   Tint offset;
46 };
47 typedef PM_FONT_INFO* pm_font_info;
48
49 #define PM_PLUS_10_NUM  9*2
50 #define PM_PLUS_15_NUM  11*2
51 #define PM_PLUS_20_NUM  13*2
52 #define PM_PLUS_25_NUM  15*2
53 #define PM_PLUS_30_NUM  17*3
54 #define PM_PLUS_35_NUM  19*3
55 #define PM_PLUS_40_NUM  21*3
56 #define PM_PLUS_45_NUM  23*3
57 #define PM_PLUS_50_NUM  25*4
58 #define PM_PLUS_55_NUM  27*4
59 #define PM_PLUS_60_NUM  29*4
60 #define PM_PLUS_65_NUM  31*4
61 #define PM_PLUS_70_NUM  32*4
62
63 #define PM_STAR_10_NUM  9
64 #define PM_STAR_15_NUM  11*2
65 #define PM_STAR_20_NUM  13*2
66 #define PM_STAR_25_NUM  15*2
67 #define PM_STAR_30_NUM  17*2
68 #define PM_STAR_35_NUM  19*2
69 #define PM_STAR_40_NUM  21*3
70 #define PM_STAR_45_NUM  23*3
71 #define PM_STAR_50_NUM  25*3
72 #define PM_STAR_55_NUM  27*3
73 #define PM_STAR_60_NUM  29*4
74 #define PM_STAR_65_NUM  32*4
75 #define PM_STAR_70_NUM  32*4
76
77 #define PM_CIRC_10_NUM  7
78 #define PM_CIRC_15_NUM  9*2
79 #define PM_CIRC_20_NUM  9*2
80 #define PM_CIRC_25_NUM  11*2
81 #define PM_CIRC_30_NUM  13*2
82 #define PM_CIRC_35_NUM  15*2
83 #define PM_CIRC_40_NUM  17*3
84 #define PM_CIRC_45_NUM  19*3
85 #define PM_CIRC_50_NUM  21*3
86 #define PM_CIRC_55_NUM  23*3
87 #define PM_CIRC_60_NUM  25*4
88 #define PM_CIRC_65_NUM  27*4
89 #define PM_CIRC_70_NUM  29*4
90
91 #define PM_CROSS_10_NUM 7
92 #define PM_CROSS_15_NUM 9*2
93 #define PM_CROSS_20_NUM 11*2
94 #define PM_CROSS_25_NUM 13*2
95 #define PM_CROSS_30_NUM 15*2
96 #define PM_CROSS_35_NUM 17*3
97 #define PM_CROSS_40_NUM 19*3
98 #define PM_CROSS_45_NUM 21*3
99 #define PM_CROSS_50_NUM 23*3
100 #define PM_CROSS_55_NUM 25*4
101 #define PM_CROSS_60_NUM 27*4
102 #define PM_CROSS_65_NUM 32*4
103 #define PM_CROSS_70_NUM 32*4
104
105 #define PM_PLUS_10_OFT  0
106 #define PM_PLUS_15_OFT  PM_PLUS_10_OFT + PM_PLUS_10_NUM
107 #define PM_PLUS_20_OFT  PM_PLUS_15_OFT + PM_PLUS_15_NUM
108 #define PM_PLUS_25_OFT  PM_PLUS_20_OFT + PM_PLUS_20_NUM
109 #define PM_PLUS_30_OFT  PM_PLUS_25_OFT + PM_PLUS_25_NUM
110 #define PM_PLUS_35_OFT  PM_PLUS_30_OFT + PM_PLUS_30_NUM
111 #define PM_PLUS_40_OFT  PM_PLUS_35_OFT + PM_PLUS_35_NUM
112 #define PM_PLUS_45_OFT  PM_PLUS_40_OFT + PM_PLUS_40_NUM
113 #define PM_PLUS_50_OFT  PM_PLUS_45_OFT + PM_PLUS_45_NUM
114 #define PM_PLUS_55_OFT  PM_PLUS_50_OFT + PM_PLUS_50_NUM
115 #define PM_PLUS_60_OFT  PM_PLUS_55_OFT + PM_PLUS_55_NUM
116 #define PM_PLUS_65_OFT  PM_PLUS_60_OFT + PM_PLUS_60_NUM
117 #define PM_PLUS_70_OFT  PM_PLUS_65_OFT + PM_PLUS_65_NUM
118
119 #define PM_STAR_10_OFT  PM_PLUS_70_OFT + PM_PLUS_70_NUM
120 #define PM_STAR_15_OFT  PM_STAR_10_OFT + PM_STAR_10_NUM
121 #define PM_STAR_20_OFT  PM_STAR_15_OFT + PM_STAR_15_NUM
122 #define PM_STAR_25_OFT  PM_STAR_20_OFT + PM_STAR_20_NUM
123 #define PM_STAR_30_OFT  PM_STAR_25_OFT + PM_STAR_25_NUM
124 #define PM_STAR_35_OFT  PM_STAR_30_OFT + PM_STAR_30_NUM
125 #define PM_STAR_40_OFT  PM_STAR_35_OFT + PM_STAR_35_NUM
126 #define PM_STAR_45_OFT  PM_STAR_40_OFT + PM_STAR_40_NUM
127 #define PM_STAR_50_OFT  PM_STAR_45_OFT + PM_STAR_45_NUM
128 #define PM_STAR_55_OFT  PM_STAR_50_OFT + PM_STAR_50_NUM
129 #define PM_STAR_60_OFT  PM_STAR_55_OFT + PM_STAR_55_NUM
130 #define PM_STAR_65_OFT  PM_STAR_60_OFT + PM_STAR_60_NUM
131 #define PM_STAR_70_OFT  PM_STAR_65_OFT + PM_STAR_65_NUM
132
133 #define PM_CIRC_10_OFT  PM_STAR_70_OFT + PM_STAR_70_NUM
134 #define PM_CIRC_15_OFT  PM_CIRC_10_OFT + PM_CIRC_10_NUM
135 #define PM_CIRC_20_OFT  PM_CIRC_15_OFT + PM_CIRC_15_NUM
136 #define PM_CIRC_25_OFT  PM_CIRC_20_OFT + PM_CIRC_20_NUM
137 #define PM_CIRC_30_OFT  PM_CIRC_25_OFT + PM_CIRC_25_NUM
138 #define PM_CIRC_35_OFT  PM_CIRC_30_OFT + PM_CIRC_30_NUM
139 #define PM_CIRC_40_OFT  PM_CIRC_35_OFT + PM_CIRC_35_NUM
140 #define PM_CIRC_45_OFT  PM_CIRC_40_OFT + PM_CIRC_40_NUM
141 #define PM_CIRC_50_OFT  PM_CIRC_45_OFT + PM_CIRC_45_NUM
142 #define PM_CIRC_55_OFT  PM_CIRC_50_OFT + PM_CIRC_50_NUM
143 #define PM_CIRC_60_OFT  PM_CIRC_55_OFT + PM_CIRC_55_NUM
144 #define PM_CIRC_65_OFT  PM_CIRC_60_OFT + PM_CIRC_60_NUM
145 #define PM_CIRC_70_OFT  PM_CIRC_65_OFT + PM_CIRC_65_NUM
146
147 #define PM_CROSS_10_OFT  PM_CIRC_70_OFT + PM_CIRC_70_NUM
148 #define PM_CROSS_15_OFT  PM_CROSS_10_OFT + PM_CROSS_10_NUM
149 #define PM_CROSS_20_OFT  PM_CROSS_15_OFT + PM_CROSS_15_NUM
150 #define PM_CROSS_25_OFT  PM_CROSS_20_OFT + PM_CROSS_20_NUM
151 #define PM_CROSS_30_OFT  PM_CROSS_25_OFT + PM_CROSS_25_NUM
152 #define PM_CROSS_35_OFT  PM_CROSS_30_OFT + PM_CROSS_30_NUM
153 #define PM_CROSS_40_OFT  PM_CROSS_35_OFT + PM_CROSS_35_NUM
154 #define PM_CROSS_45_OFT  PM_CROSS_40_OFT + PM_CROSS_40_NUM
155 #define PM_CROSS_50_OFT  PM_CROSS_45_OFT + PM_CROSS_45_NUM
156 #define PM_CROSS_55_OFT  PM_CROSS_50_OFT + PM_CROSS_50_NUM
157 #define PM_CROSS_60_OFT  PM_CROSS_55_OFT + PM_CROSS_55_NUM
158 #define PM_CROSS_65_OFT  PM_CROSS_60_OFT + PM_CROSS_60_NUM
159 #define PM_CROSS_70_OFT  PM_CROSS_65_OFT + PM_CROSS_65_NUM
160
161 static const PM_FONT_INFO arrPMFontInfo[][TEL_NO_OF_SIZES] =
162 {
163  // TOM_POINT - not used
164  {{0},
165   {0},
166   {0},
167   {0},
168   {0},
169   {0},
170   {0},
171   {0},
172   {0},
173   {0},
174   {0},
175   {0},
176   {0}},
177
178  // TOM_PLUS
179  {{ 9.f,  9.f, PM_PLUS_10_OFT},
180   {11.f, 11.f, PM_PLUS_15_OFT},
181   {13.f, 13.f, PM_PLUS_20_OFT},
182   {15.f, 15.f, PM_PLUS_25_OFT},
183   {17.f, 17.f, PM_PLUS_30_OFT},
184   {19.f, 19.f, PM_PLUS_35_OFT},
185   {21.f, 21.f, PM_PLUS_40_OFT},
186   {23.f, 23.f, PM_PLUS_45_OFT},
187   {25.f, 25.f, PM_PLUS_50_OFT},
188   {27.f, 27.f, PM_PLUS_55_OFT},
189   {29.f, 29.f, PM_PLUS_60_OFT},
190   {31.f, 31.f, PM_PLUS_65_OFT},
191   {32.f, 32.f, PM_PLUS_70_OFT}},
192
193  // TOM_STAR
194  {{ 7.f,  9.f, PM_STAR_10_OFT},
195   {9.f,  11.f, PM_STAR_15_OFT},
196   {11.f, 13.f, PM_STAR_20_OFT},
197   {13.f, 15.f, PM_STAR_25_OFT},
198   {13.f, 17.f, PM_STAR_30_OFT},
199   {15.f, 19.f, PM_STAR_35_OFT},
200   {17.f, 21.f, PM_STAR_40_OFT},
201   {19.f, 23.f, PM_STAR_45_OFT},
202   {21.f, 25.f, PM_STAR_50_OFT},
203   {23.f, 27.f, PM_STAR_55_OFT},
204   {25.f, 29.f, PM_STAR_60_OFT},
205   {32.f, 32.f, PM_STAR_65_OFT},
206   {32.f, 32.f, PM_STAR_70_OFT}},
207
208  // TOM_X
209  {{ 7.f,  7.f, PM_CROSS_10_OFT},
210   { 9.f,  9.f, PM_CROSS_15_OFT},
211   {11.f, 11.f, PM_CROSS_20_OFT},
212   {13.f, 13.f, PM_CROSS_25_OFT},
213   {15.f, 15.f, PM_CROSS_30_OFT},
214   {17.f, 17.f, PM_CROSS_35_OFT},
215   {19.f, 19.f, PM_CROSS_40_OFT},
216   {21.f, 21.f, PM_CROSS_45_OFT},
217   {23.f, 23.f, PM_CROSS_50_OFT},
218   {25.f, 25.f, PM_CROSS_55_OFT},
219   {27.f, 27.f, PM_CROSS_60_OFT},
220   {32.f, 32.f, PM_CROSS_65_OFT},
221   {32.f, 32.f, PM_CROSS_70_OFT}},
222
223  // TOM_O
224  {{ 7.f,  7.f, PM_CIRC_10_OFT},
225   { 9.f,  9.f, PM_CIRC_15_OFT},
226   { 9.f,  9.f, PM_CIRC_20_OFT},
227   {11.f, 11.f, PM_CIRC_25_OFT},
228   {13.f, 13.f, PM_CIRC_30_OFT},
229   {15.f, 15.f, PM_CIRC_35_OFT},
230   {17.f, 17.f, PM_CIRC_40_OFT},
231   {19.f, 19.f, PM_CIRC_45_OFT},
232   {21.f, 21.f, PM_CIRC_50_OFT},
233   {23.f, 23.f, PM_CIRC_55_OFT},
234   {25.f, 25.f, PM_CIRC_60_OFT},
235   {27.f, 27.f, PM_CIRC_65_OFT},
236   {29.f, 29.f, PM_CIRC_70_OFT}}
237 };
238
239 static const Standard_Byte OpenGl_AspectMarker_myMarkerRaster[] =
240 {
241     // TYPE = PLUS
242
243     0x08,0x00,
244     0x08,0x00,
245     0x08,0x00,
246     0x08,0x00,
247     0xff,0x80,
248     0x08,0x00,
249     0x08,0x00,
250     0x08,0x00,
251     0x08,0x00, // PLUS 9x9 = 1.0
252
253     0x04,0x00,
254     0x04,0x00,
255     0x04,0x00,
256     0x04,0x00,
257     0x04,0x00,
258     0xff,0xe0,
259     0x04,0x00,
260     0x04,0x00,
261     0x04,0x00,
262     0x04,0x00,
263     0x04,0x00, // PLUS 11x11 = 1.5
264
265     0x02,0x00,
266     0x02,0x00,
267     0x02,0x00,
268     0x02,0x00,
269     0x02,0x00,
270     0x02,0x00,
271     0xff,0xf8,
272     0x02,0x00,
273     0x02,0x00,
274     0x02,0x00,
275     0x02,0x00,
276     0x02,0x00,
277     0x02,0x00, // PLUS 13x13 = 2.0
278
279     0x01,0x00,
280     0x01,0x00,
281     0x01,0x00,
282     0x01,0x00,
283     0x01,0x00,
284     0x01,0x00,
285     0x01,0x00,
286     0xff,0xfe,
287     0x01,0x00,
288     0x01,0x00,
289     0x01,0x00,
290     0x01,0x00,
291     0x01,0x00,
292     0x01,0x00,
293     0x01,0x00, // PLUS 15x15 = 2.5
294
295     0x00,0x80, 0x00,
296     0x00,0x80, 0x00,
297     0x00,0x80, 0x00,
298     0x00,0x80, 0x00,
299     0x00,0x80, 0x00,
300     0x00,0x80, 0x00,
301     0x00,0x80, 0x00,
302     0x00,0x80, 0x00,
303     0xff,0xff, 0x80,
304     0x00,0x80, 0x00,
305     0x00,0x80, 0x00,
306     0x00,0x80, 0x00,
307     0x00,0x80, 0x00,
308     0x00,0x80, 0x00,
309     0x00,0x80, 0x00,
310     0x00,0x80, 0x00,
311     0x00,0x80, 0x00, // PLUS 17x17 = 3.0
312
313     0x00,0x40, 0x00,
314     0x00,0x40, 0x00,
315     0x00,0x40, 0x00,
316     0x00,0x40, 0x00,
317     0x00,0x40, 0x00,
318     0x00,0x40, 0x00,
319     0x00,0x40, 0x00,
320     0x00,0x40, 0x00,
321     0x00,0x40, 0x00,
322     0xff,0xff, 0xe0,
323     0x00,0x40, 0x00,
324     0x00,0x40, 0x00,
325     0x00,0x40, 0x00,
326     0x00,0x40, 0x00,
327     0x00,0x40, 0x00,
328     0x00,0x40, 0x00,
329     0x00,0x40, 0x00,
330     0x00,0x40, 0x00,
331     0x00,0x40, 0x00, // PLUS 19x19 = 3.5
332
333     0x00,0x20, 0x00,
334     0x00,0x20, 0x00,
335     0x00,0x20, 0x00,
336     0x00,0x20, 0x00,
337     0x00,0x20, 0x00,
338     0x00,0x20, 0x00,
339     0x00,0x20, 0x00,
340     0x00,0x20, 0x00,
341     0x00,0x20, 0x00,
342     0x00,0x20, 0x00,
343     0xff,0xff, 0xf8,
344     0x00,0x20, 0x00,
345     0x00,0x20, 0x00,
346     0x00,0x20, 0x00,
347     0x00,0x20, 0x00,
348     0x00,0x20, 0x00,
349     0x00,0x20, 0x00,
350     0x00,0x20, 0x00,
351     0x00,0x20, 0x00,
352     0x00,0x20, 0x00,
353     0x00,0x20, 0x00, // PLUS 21x21 = 4.0
354
355     0x00,0x10, 0x00,
356     0x00,0x10, 0x00,
357     0x00,0x10, 0x00,
358     0x00,0x10, 0x00,
359     0x00,0x10, 0x00,
360     0x00,0x10, 0x00,
361     0x00,0x10, 0x00,
362     0x00,0x10, 0x00,
363     0x00,0x10, 0x00,
364     0x00,0x10, 0x00,
365     0x00,0x10, 0x00,
366     0xff,0xff, 0xfe,
367     0x00,0x10, 0x00,
368     0x00,0x10, 0x00,
369     0x00,0x10, 0x00,
370     0x00,0x10, 0x00,
371     0x00,0x10, 0x00,
372     0x00,0x10, 0x00,
373     0x00,0x10, 0x00,
374     0x00,0x10, 0x00,
375     0x00,0x10, 0x00,
376     0x00,0x10, 0x00,
377     0x00,0x10, 0x00, // PLUS 23x23 = 4.5
378
379     0x00,0x08, 0x00,0x00,
380     0x00,0x08, 0x00,0x00,
381     0x00,0x08, 0x00,0x00,
382     0x00,0x08, 0x00,0x00,
383     0x00,0x08, 0x00,0x00,
384     0x00,0x08, 0x00,0x00,
385     0x00,0x08, 0x00,0x00,
386     0x00,0x08, 0x00,0x00,
387     0x00,0x08, 0x00,0x00,
388     0x00,0x08, 0x00,0x00,
389     0x00,0x08, 0x00,0x00,
390     0x00,0x08, 0x00,0x00,
391     0xff,0xff, 0xff,0x80,
392     0x00,0x08, 0x00,0x00,
393     0x00,0x08, 0x00,0x00,
394     0x00,0x08, 0x00,0x00,
395     0x00,0x08, 0x00,0x00,
396     0x00,0x08, 0x00,0x00,
397     0x00,0x08, 0x00,0x00,
398     0x00,0x08, 0x00,0x00,
399     0x00,0x08, 0x00,0x00,
400     0x00,0x08, 0x00,0x00,
401     0x00,0x08, 0x00,0x00,
402     0x00,0x08, 0x00,0x00,
403     0x00,0x08, 0x00,0x00, // PLUS 25x25 = 5.0
404
405     0x00,0x04, 0x00,0x00,
406     0x00,0x04, 0x00,0x00,
407     0x00,0x04, 0x00,0x00,
408     0x00,0x04, 0x00,0x00,
409     0x00,0x04, 0x00,0x00,
410     0x00,0x04, 0x00,0x00,
411     0x00,0x04, 0x00,0x00,
412     0x00,0x04, 0x00,0x00,
413     0x00,0x04, 0x00,0x00,
414     0x00,0x04, 0x00,0x00,
415     0x00,0x04, 0x00,0x00,
416     0x00,0x04, 0x00,0x00,
417     0x00,0x04, 0x00,0x00,
418     0xff,0xff, 0xff,0xe0,
419     0x00,0x04, 0x00,0x00,
420     0x00,0x04, 0x00,0x00,
421     0x00,0x04, 0x00,0x00,
422     0x00,0x04, 0x00,0x00,
423     0x00,0x04, 0x00,0x00,
424     0x00,0x04, 0x00,0x00,
425     0x00,0x04, 0x00,0x00,
426     0x00,0x04, 0x00,0x00,
427     0x00,0x04, 0x00,0x00,
428     0x00,0x04, 0x00,0x00,
429     0x00,0x04, 0x00,0x00,
430     0x00,0x04, 0x00,0x00,
431     0x00,0x04, 0x00,0x00, // PLUS 27x27 = 5.5
432
433     0x00,0x02, 0x00,0x00,
434     0x00,0x02, 0x00,0x00,
435     0x00,0x02, 0x00,0x00,
436     0x00,0x02, 0x00,0x00,
437     0x00,0x02, 0x00,0x00,
438     0x00,0x02, 0x00,0x00,
439     0x00,0x02, 0x00,0x00,
440     0x00,0x02, 0x00,0x00,
441     0x00,0x02, 0x00,0x00,
442     0x00,0x02, 0x00,0x00,
443     0x00,0x02, 0x00,0x00,
444     0x00,0x02, 0x00,0x00,
445     0x00,0x02, 0x00,0x00,
446     0x00,0x02, 0x00,0x00,
447     0xff,0xff, 0xff,0xf8,
448     0x00,0x02, 0x00,0x00,
449     0x00,0x02, 0x00,0x00,
450     0x00,0x02, 0x00,0x00,
451     0x00,0x02, 0x00,0x00,
452     0x00,0x02, 0x00,0x00,
453     0x00,0x02, 0x00,0x00,
454     0x00,0x02, 0x00,0x00,
455     0x00,0x02, 0x00,0x00,
456     0x00,0x02, 0x00,0x00,
457     0x00,0x02, 0x00,0x00,
458     0x00,0x02, 0x00,0x00,
459     0x00,0x02, 0x00,0x00,
460     0x00,0x02, 0x00,0x00,
461     0x00,0x02, 0x00,0x00, // PLUS 29x29 = 6.0
462
463     0x00,0x01, 0x00,0x00,
464     0x00,0x01, 0x00,0x00,
465     0x00,0x01, 0x00,0x00,
466     0x00,0x01, 0x00,0x00,
467     0x00,0x01, 0x00,0x00,
468     0x00,0x01, 0x00,0x00,
469     0x00,0x01, 0x00,0x00,
470     0x00,0x01, 0x00,0x00,
471     0x00,0x01, 0x00,0x00,
472     0x00,0x01, 0x00,0x00,
473     0x00,0x01, 0x00,0x00,
474     0x00,0x01, 0x00,0x00,
475     0x00,0x01, 0x00,0x00,
476     0x00,0x01, 0x00,0x00,
477     0x00,0x01, 0x00,0x00,
478     0xff,0xff, 0xff,0xfd,
479     0x00,0x01, 0x00,0x00,
480     0x00,0x01, 0x00,0x00,
481     0x00,0x01, 0x00,0x00,
482     0x00,0x01, 0x00,0x00,
483     0x00,0x01, 0x00,0x00,
484     0x00,0x01, 0x00,0x00,
485     0x00,0x01, 0x00,0x00,
486     0x00,0x01, 0x00,0x00,
487     0x00,0x01, 0x00,0x00,
488     0x00,0x01, 0x00,0x00,
489     0x00,0x01, 0x00,0x00,
490     0x00,0x01, 0x00,0x00,
491     0x00,0x01, 0x00,0x00,
492     0x00,0x01, 0x00,0x00,
493     0x00,0x01, 0x00,0x00, // PLUS 31x31 = 6.5
494
495     0x00,0x00, 0x80,0x00,
496     0x00,0x00, 0x80,0x00,
497     0x00,0x00, 0x80,0x00,
498     0x00,0x00, 0x80,0x00,
499     0x00,0x00, 0x80,0x00,
500     0x00,0x00, 0x80,0x00,
501     0x00,0x00, 0x80,0x00,
502     0x00,0x00, 0x80,0x00,
503     0x00,0x00, 0x80,0x00,
504     0x00,0x00, 0x80,0x00,
505     0x00,0x00, 0x80,0x00,
506     0x00,0x00, 0x80,0x00,
507     0x00,0x00, 0x80,0x00,
508     0x00,0x00, 0x80,0x00,
509     0x00,0x00, 0x80,0x00,
510     0x00,0x00, 0x80,0x00,
511     0xff,0xff, 0xff,0xff,
512     0x00,0x00, 0x80,0x00,
513     0x00,0x00, 0x80,0x00,
514     0x00,0x00, 0x80,0x00,
515     0x00,0x00, 0x80,0x00,
516     0x00,0x00, 0x80,0x00,
517     0x00,0x00, 0x80,0x00,
518     0x00,0x00, 0x80,0x00,
519     0x00,0x00, 0x80,0x00,
520     0x00,0x00, 0x80,0x00,
521     0x00,0x00, 0x80,0x00,
522     0x00,0x00, 0x80,0x00,
523     0x00,0x00, 0x80,0x00,
524     0x00,0x00, 0x80,0x00,
525     0x00,0x00, 0x80,0x00,
526     0x00,0x00, 0x80,0x00, // PLUS 32x32 = 7.0
527
528     // TYPE = STAR
529
530     0x10,
531     0x10,
532     0xd6,
533     0x38,
534     0x10,
535     0x38,
536     0xd6,
537     0x10,
538     0x10, // STAR 7x9 = 1.0
539
540     0x08,0x00,
541     0x08,0x00,
542     0x08,0x00,
543     0xc9,0x80,
544     0x3e,0x00,
545     0x08,0x00,
546     0x3e,0x00,
547     0xc9,0x80,
548     0x08,0x00,
549     0x08,0x00,
550     0x08,0x00, // STAR 9x11 = 1.5
551
552     0x04,0x00,
553     0x04,0x00,
554     0x04,0x00,
555     0x84,0x20,
556     0x64,0xc0,
557     0x1f,0x00,
558     0x04,0x00,
559     0x1f,0x00,
560     0x64,0xc0,
561     0x84,0x20,
562     0x04,0x00,
563     0x04,0x00,
564     0x04,0x00, // STAR 11x13 = 2.0
565
566     0x02,0x00,
567     0x02,0x00,
568     0x02,0x00,
569     0x02,0x00,
570     0x82,0x18,
571     0x62,0x60,
572     0x1b,0x80,
573     0x06,0x00,
574     0x1b,0x80,
575     0x62,0x60,
576     0x82,0x18,
577     0x02,0x00,
578     0x02,0x00,
579     0x02,0x00,
580     0x02,0x00, // STAR 13x15 = 2.5
581
582     0x02,0x00,
583     0x02,0x00,
584     0x02,0x00,
585     0x02,0x00,
586     0x82,0x08,
587     0x62,0x30,
588     0x12,0x40,
589     0x0f,0x80,
590     0x02,0x00,
591     0x0f,0x80,
592     0x12,0x40,
593     0x62,0x30,
594     0x82,0x08,
595     0x02,0x00,
596     0x02,0x00,
597     0x02,0x00,
598     0x02,0x00, // STAR 13x17 = 3.0
599
600     0x01,0x00,
601     0x01,0x00,
602     0x01,0x00,
603     0x01,0x00,
604     0x01,0x00,
605     0xc1,0x06,
606     0x21,0x18,
607     0x19,0x20,
608     0x07,0xc0,
609     0x01,0x00,
610     0x07,0xc0,
611     0x19,0x20,
612     0x21,0x18,
613     0xc1,0x06,
614     0x01,0x00,
615     0x01,0x00,
616     0x01,0x00,
617     0x01,0x00,
618     0x01,0x00, // STAR 15x19 = 3.5
619
620     0x00,0x80, 0x00,
621     0x00,0x80, 0x00,
622     0x00,0x80, 0x00,
623     0x00,0x80, 0x00,
624     0x00,0x80, 0x00,
625     0x80,0x80, 0x80,
626     0x60,0x83, 0x00,
627     0x10,0x8c, 0x00,
628     0x0c,0x90, 0x00,
629     0x03,0xe0, 0x00,
630     0x00,0x80, 0x00,
631     0x03,0xe0, 0x00,
632     0x0c,0x90, 0x00,
633     0x10,0x8c, 0x00,
634     0x60,0x83, 0x00,
635     0x80,0x80, 0x80,
636     0x00,0x80, 0x00,
637     0x00,0x80, 0x00,
638     0x00,0x80, 0x00,
639     0x00,0x80, 0x00,
640     0x00,0x80, 0x00, // STAR 17x21 = 4.0
641
642     0x00,0x40, 0x00,
643     0x00,0x40, 0x00,
644     0x00,0x40, 0x00,
645     0x00,0x40, 0x00,
646     0x00,0x40, 0x00,
647     0x00,0x40, 0x00,
648     0xc0,0x40, 0x60,
649     0x30,0x41, 0x80,
650     0x08,0x42, 0x00,
651     0x06,0x4c, 0x00,
652     0x01,0xf0, 0x00,
653     0x00,0x40, 0x00,
654     0x01,0xf0, 0x00,
655     0x06,0x4c, 0x00,
656     0x08,0x42, 0x00,
657     0x30,0x41, 0x80,
658     0xc0,0x40, 0x60,
659     0x00,0x40, 0x00,
660     0x00,0x40, 0x00,
661     0x00,0x40, 0x00,
662     0x00,0x40, 0x00,
663     0x00,0x40, 0x00,
664     0x00,0x40, 0x00, // STAR 19x23 = 4.5
665
666     0x00,0x20, 0x00,
667     0x00,0x20, 0x00,
668     0x00,0x20, 0x00,
669     0x00,0x20, 0x00,
670     0x00,0x20, 0x00,
671     0x00,0x20, 0x00,
672     0x80,0x20, 0x08,
673     0x60,0x20, 0x30,
674     0x18,0x20, 0xc0,
675     0x04,0x21, 0x00,
676     0x03,0x26, 0x00,
677     0x00,0xf8, 0x00,
678     0x00,0x20, 0x00,
679     0x00,0xf8, 0x00,
680     0x03,0x26, 0x00,
681     0x04,0x21, 0x00,
682     0x18,0x20, 0xc0,
683     0x60,0x20, 0x30,
684     0x80,0x20, 0x08,
685     0x00,0x20, 0x00,
686     0x00,0x20, 0x00,
687     0x00,0x20, 0x00,
688     0x00,0x20, 0x00,
689     0x00,0x20, 0x00,
690     0x00,0x20, 0x00, // STAR 21x25 = 5.0
691
692     0x00,0x10, 0x00,
693     0x00,0x10, 0x00,
694     0x00,0x10, 0x00,
695     0x00,0x10, 0x00,
696     0x00,0x10, 0x00,
697     0x00,0x10, 0x00,
698     0x00,0x10, 0x00,
699     0xc0,0x10, 0x06,
700     0x30,0x10, 0x18,
701     0x08,0x10, 0x60,
702     0x06,0x10, 0x80,
703     0x01,0x93, 0x00,
704     0x00,0x7c, 0x00,
705     0x00,0x10, 0x00,
706     0x00,0x7c, 0x00,
707     0x01,0x93, 0x00,
708     0x06,0x10, 0x80,
709     0x08,0x10, 0x60,
710     0x30,0x10, 0x18,
711     0xc0,0x10, 0x06,
712     0x00,0x10, 0x00,
713     0x00,0x10, 0x00,
714     0x00,0x10, 0x00,
715     0x00,0x10, 0x00,
716     0x00,0x10, 0x00,
717     0x00,0x10, 0x00,
718     0x00,0x10, 0x00, // STAR 23x27 = 5.5
719
720     0x00,0x08, 0x00,0x00,
721     0x00,0x08, 0x00,0x00,
722     0x00,0x08, 0x00,0x00,
723     0x00,0x08, 0x00,0x00,
724     0x00,0x08, 0x00,0x00,
725     0x00,0x08, 0x00,0x00,
726     0x00,0x08, 0x00,0x00,
727     0x80,0x08, 0x00,0x80,
728     0x60,0x08, 0x03,0x00,
729     0x18,0x08, 0x0c,0x00,
730     0x04,0x08, 0x30,0x00,
731     0x03,0x08, 0x40,0x00,
732     0x00,0xc9, 0x80,0x00,
733     0x00,0x3e, 0x00,0x00,
734     0x00,0x08, 0x00,0x00,
735     0x00,0x3e, 0x00,0x00,
736     0x00,0xc9, 0x80,0x00,
737     0x03,0x08, 0x40,0x00,
738     0x04,0x08, 0x30,0x00,
739     0x18,0x08, 0x0c,0x00,
740     0x60,0x08, 0x03,0x00,
741     0x80,0x08, 0x00,0x80,
742     0x00,0x08, 0x00,0x00,
743     0x00,0x08, 0x00,0x00,
744     0x00,0x08, 0x00,0x00,
745     0x00,0x08, 0x00,0x00,
746     0x00,0x08, 0x00,0x00,
747     0x00,0x08, 0x00,0x00,
748     0x00,0x08, 0x00,0x00, // STAR 25x29 = 6.0
749
750     0x00,0x00, 0x80,0x00,
751     0x00,0x00, 0x80,0x00,
752     0x00,0x00, 0x80,0x00,
753     0x00,0x00, 0x80,0x00,
754     0x00,0x00, 0x80,0x00,
755     0x00,0x00, 0x80,0x00,
756     0x00,0x00, 0x80,0x00,
757     0x00,0x00, 0x80,0x00,
758     0x00,0x00, 0x80,0x00,
759     0x30,0x00, 0x80,0x06,
760     0x0c,0x00, 0x80,0x18,
761     0x03,0x00, 0x80,0x60,
762     0x00,0xc0, 0x81,0x80,
763     0x00,0x30, 0x86,0x00,
764     0x00,0x0c, 0x98,0x00,
765     0x00,0x03, 0xe0,0x00,
766     0x00,0x03, 0xe0,0x00,
767     0x00,0x0c, 0x98,0x00,
768     0x00,0x30, 0x86,0x00,
769     0x00,0xc0, 0x81,0x80,
770     0x03,0x00, 0x80,0x60,
771     0x0c,0x00, 0x80,0x18,
772     0x30,0x00, 0x80,0x06,
773     0x00,0x00, 0x80,0x00,
774     0x00,0x00, 0x80,0x00,
775     0x00,0x00, 0x80,0x00,
776     0x00,0x00, 0x80,0x00,
777     0x00,0x00, 0x80,0x00,
778     0x00,0x00, 0x80,0x00,
779     0x00,0x00, 0x80,0x00,
780     0x00,0x00, 0x00,0x00,
781     0x00,0x00, 0x00,0x00, // STAR 32x32 = 6.5
782
783     0x00, 0x00, 0x80, 0x00,
784     0x00, 0x00, 0x80, 0x00,
785     0x00, 0x00, 0x80, 0x00,
786     0x00, 0x00, 0x80, 0x00,
787     0x00, 0x00, 0x80, 0x00,
788     0x00, 0x00, 0x80, 0x00,
789     0x00, 0x00, 0x80, 0x00,
790     0x00, 0x00, 0x80, 0x00,
791     0x10, 0x00, 0x80, 0x04,
792     0x0c, 0x00, 0x80, 0x18,
793     0x02, 0x00, 0x80, 0x20,
794     0x01, 0x80, 0x80, 0xc0,
795     0x00, 0x40, 0x81, 0x00,
796     0x00, 0x30, 0x86, 0x00,
797     0x00, 0x08, 0x88, 0x00,
798     0x00, 0x06, 0xb0, 0x00,
799     0x00, 0x01, 0xc0, 0x00,
800     0x00, 0x06, 0xb0, 0x00,
801     0x00, 0x08, 0x88, 0x00,
802     0x00, 0x30, 0x86, 0x00,
803     0x00, 0x40, 0x81, 0x00,
804     0x01, 0x80, 0x80, 0xc0,
805     0x02, 0x00, 0x80, 0x20,
806     0x0c, 0x00, 0x80, 0x18,
807     0x10, 0x00, 0x80, 0x04,
808     0x00, 0x00, 0x80, 0x00,
809     0x00, 0x00, 0x80, 0x00,
810     0x00, 0x00, 0x80, 0x00,
811     0x00, 0x00, 0x80, 0x00,
812     0x00, 0x00, 0x80, 0x00,
813     0x00, 0x00, 0x80, 0x00,
814     0x00, 0x00, 0x80, 0x00, // STAR 32x32 = 7.0
815
816     // TYPE = CIRC
817
818     0x38,
819     0x44,
820     0x82,
821     0x82,
822     0x82,
823     0x44,
824     0x38, // CIRC 7x7 = 1.0
825
826     0x3c,0x00,
827     0x42,0x00,
828     0x81,0x00,
829     0x81,0x00,
830     0x81,0x00,
831     0x81,0x00,
832     0x42,0x00,
833     0x3c,0x00,
834     0x00,0x00, //CIRC 9x9 = 1.5
835
836     0x3e,0x00,
837     0x41,0x00,
838     0x81,0x80,
839     0x80,0x80,
840     0x80,0x80,
841     0x80,0x80,
842     0x81,0x80,
843     0x41,0x00,
844     0x3e,0x00, // CIRC 9x9 = 2.0
845
846     0x1f,0x00,
847     0x20,0x80,
848     0x40,0x40,
849     0x80,0x20,
850     0x80,0x20,
851     0x80,0x20,
852     0x80,0x20,
853     0x80,0x20,
854     0x40,0x40,
855     0x20,0x80,
856     0x1f,0x00, // CIRC 11x11 = 2.5
857
858     0x0f,0x80,
859     0x10,0x40,
860     0x20,0x20,
861     0x40,0x10,
862     0x80,0x08,
863     0x80,0x08,
864     0x80,0x08,
865     0x80,0x08,
866     0x80,0x08,
867     0x40,0x10,
868     0x20,0x20,
869     0x10,0x40,
870     0x0f,0x80, // CIRC 13x13 = 3.0
871
872     0x07,0xc0,
873     0x18,0x30,
874     0x20,0x08,
875     0x40,0x04,
876     0x40,0x04,
877     0x80,0x02,
878     0x80,0x02,
879     0x80,0x02,
880     0x80,0x02,
881     0x80,0x02,
882     0x40,0x04,
883     0x40,0x04,
884     0x20,0x08,
885     0x18,0x30,
886     0x07,0xc0, // CIRC 15x15 = 3.5
887
888     0x03,0xe0, 0x00,
889     0x0c,0x18, 0x00,
890     0x10,0x04, 0x00,
891     0x20,0x02, 0x00,
892     0x40,0x01, 0x00,
893     0x40,0x01, 0x00,
894     0x80,0x00, 0x80,
895     0x80,0x00, 0x80,
896     0x80,0x00, 0x80,
897     0x80,0x00, 0x80,
898     0x80,0x00, 0x80,
899     0x40,0x01, 0x00,
900     0x40,0x01, 0x00,
901     0x20,0x02, 0x00,
902     0x10,0x04, 0x00,
903     0x0c,0x18, 0x00,
904     0x03,0xe0, 0x00, // CIRC 17x17 = 4.0
905
906     0x03,0xf8, 0x00,
907     0x0e,0x0e, 0x00,
908     0x18,0x03, 0x00,
909     0x20,0x00, 0x80,
910     0x60,0x00, 0xc0,
911     0x40,0x00, 0x40,
912     0xc0,0x00, 0x60,
913     0x80,0x00, 0x20,
914     0x80,0x00, 0x20,
915     0x80,0x00, 0x20,
916     0x80,0x00, 0x20,
917     0x80,0x00, 0x20,
918     0xc0,0x00, 0x60,
919     0x40,0x00, 0x40,
920     0x60,0x00, 0xc0,
921     0x20,0x00, 0x80,
922     0x18,0x03, 0x00,
923     0x0e,0x0e, 0x00,
924     0x03,0xf8, 0x00, // CIRC 19x19 = 4.5
925
926     0x01,0xfc, 0x00,
927     0x06,0x03, 0x00,
928     0x08,0x00, 0x80,
929     0x10,0x00, 0x40,
930     0x20,0x00, 0x20,
931     0x40,0x00, 0x10,
932     0x40,0x00, 0x10,
933     0x80,0x00, 0x08,
934     0x80,0x00, 0x08,
935     0x80,0x00, 0x08,
936     0x80,0x00, 0x08,
937     0x80,0x00, 0x08,
938     0x80,0x00, 0x08,
939     0x80,0x00, 0x08,
940     0x40,0x00, 0x10,
941     0x40,0x00, 0x10,
942     0x20,0x00, 0x20,
943     0x10,0x00, 0x40,
944     0x08,0x00, 0x80,
945     0x06,0x03, 0x00,
946     0x01,0xfc, 0x00, // CIRC 21x21 = 5.0
947
948     0x00,0xfe, 0x00,
949     0x03,0x01, 0x80,
950     0x0c,0x00, 0x60,
951     0x18,0x00, 0x30,
952     0x30,0x00, 0x18,
953     0x20,0x00, 0x08,
954     0x40,0x00, 0x04,
955     0x40,0x00, 0x04,
956     0x80,0x00, 0x02,
957     0x80,0x00, 0x02,
958     0x80,0x00, 0x02,
959     0x80,0x00, 0x02,
960     0x80,0x00, 0x02,
961     0x80,0x00, 0x02,
962     0x80,0x00, 0x02,
963     0x40,0x00, 0x04,
964     0x40,0x00, 0x04,
965     0x20,0x00, 0x08,
966     0x30,0x00, 0x18,
967     0x18,0x00, 0x30,
968     0x0c,0x00, 0x60,
969     0x03,0x01, 0x80,
970     0x00,0xfe, 0x00, // CIRC 23x23 = 5.5
971
972     0x00,0x7f, 0x00,0x00,
973     0x01,0x80, 0xc0,0x00,
974     0x06,0x00, 0x30,0x00,
975     0x08,0x00, 0x08,0x00,
976     0x10,0x00, 0x04,0x00,
977     0x20,0x00, 0x02,0x00,
978     0x20,0x00, 0x02,0x00,
979     0x40,0x00, 0x01,0x00,
980     0x40,0x00, 0x01,0x00,
981     0x80,0x00, 0x00,0x80,
982     0x80,0x00, 0x00,0x80,
983     0x80,0x00, 0x00,0x80,
984     0x80,0x00, 0x00,0x80,
985     0x80,0x00, 0x00,0x80,
986     0x80,0x00, 0x00,0x80,
987     0x80,0x00, 0x00,0x80,
988     0x40,0x00, 0x01,0x00,
989     0x40,0x00, 0x01,0x00,
990     0x20,0x00, 0x02,0x00,
991     0x20,0x00, 0x02,0x00,
992     0x10,0x00, 0x04,0x00,
993     0x08,0x00, 0x08,0x00,
994     0x06,0x00, 0x30,0x00,
995     0x01,0x80, 0xc0,0x00,
996     0x00,0x7f, 0x00,0x00, // CIRC 25x25 = 6.0
997
998     0x00,0x3f, 0x80,0x00,
999     0x01,0xc0, 0x70,0x00,
1000     0x03,0x00, 0x18,0x00,
1001     0x0c,0x00, 0x06,0x00,
1002     0x18,0x00, 0x03,0x00,
1003     0x10,0x00, 0x01,0x00,
1004     0x20,0x00, 0x00,0x80,
1005     0x60,0x00, 0x00,0xc0,
1006     0x40,0x00, 0x00,0x40,
1007     0x40,0x00, 0x00,0x40,
1008     0x80,0x00, 0x00,0x20,
1009     0x80,0x00, 0x00,0x20,
1010     0x80,0x00, 0x00,0x20,
1011     0x80,0x00, 0x00,0x20,
1012     0x80,0x00, 0x00,0x20,
1013     0x80,0x00, 0x00,0x20,
1014     0x80,0x00, 0x00,0x20,
1015     0x40,0x00, 0x00,0x40,
1016     0x40,0x00, 0x00,0x40,
1017     0x60,0x00, 0x00,0xc0,
1018     0x20,0x00, 0x00,0x80,
1019     0x10,0x00, 0x01,0x00,
1020     0x18,0x00, 0x03,0x00,
1021     0x0c,0x00, 0x06,0x00,
1022     0x03,0x00, 0x18,0x00,
1023     0x01,0xc0, 0x70,0x00,
1024     0x00,0x3f, 0x80,0x00, // CIRC 27x27 = 6.5
1025
1026     0x00,0x1f, 0xc0,0x00,
1027     0x00,0xe0, 0x38,0x00,
1028     0x01,0x00, 0x04,0x00,
1029     0x06,0x00, 0x03,0x00,
1030     0x08,0x00, 0x00,0x80,
1031     0x10,0x00, 0x00,0x40,
1032     0x10,0x00, 0x00,0x40,
1033     0x20,0x00, 0x00,0x20,
1034     0x40,0x00, 0x00,0x10,
1035     0x40,0x00, 0x00,0x10,
1036     0x40,0x00, 0x00,0x10,
1037     0x80,0x00, 0x00,0x08,
1038     0x80,0x00, 0x00,0x08,
1039     0x80,0x00, 0x00,0x08,
1040     0x80,0x00, 0x00,0x08,
1041     0x80,0x00, 0x00,0x08,
1042     0x80,0x00, 0x00,0x08,
1043     0x80,0x00, 0x00,0x08,
1044     0x40,0x00, 0x00,0x10,
1045     0x40,0x00, 0x00,0x10,
1046     0x40,0x00, 0x00,0x10,
1047     0x20,0x00, 0x00,0x20,
1048     0x10,0x00, 0x00,0x40,
1049     0x10,0x00, 0x00,0x40,
1050     0x08,0x00, 0x00,0x80,
1051     0x06,0x00, 0x03,0x00,
1052     0x01,0x00, 0x04,0x00,
1053     0x00,0xe0, 0x38,0x00,
1054     0x00,0x1f, 0xc0,0x00, // CIRC 29x29 = 7.0
1055
1056     // TYPE = CROSS
1057
1058     0x82,
1059     0x44,
1060     0x28,
1061     0x10,
1062     0x28,
1063     0x44,
1064     0x82, // CROSS 7x7 = 1.0
1065
1066     0x80,0x80,
1067     0x41,0x00,
1068     0x22,0x00,
1069     0x14,0x00,
1070     0x08,0x00,
1071     0x14,0x00,
1072     0x22,0x00,
1073     0x41,0x00,
1074     0x80,0x80, // CROSS 9x9 = 1.5
1075
1076     0x80,0x20,
1077     0x40,0x40,
1078     0x20,0x80,
1079     0x11,0x00,
1080     0x0a,0x00,
1081     0x04,0x00,
1082     0x0a,0x00,
1083     0x11,0x00,
1084     0x20,0x80,
1085     0x40,0x40,
1086     0x80,0x20, // CROSS 11x11 = 2.0
1087
1088     0x80,0x08,
1089     0x40,0x10,
1090     0x20,0x20,
1091     0x10,0x40,
1092     0x08,0x80,
1093     0x05,0x00,
1094     0x02,0x00,
1095     0x05,0x00,
1096     0x08,0x80,
1097     0x10,0x40,
1098     0x20,0x20,
1099     0x40,0x10,
1100     0x80,0x08, // CROSS 13x13 = 2.5
1101
1102     0x80,0x02,
1103     0x40,0x04,
1104     0x20,0x08,
1105     0x10,0x10,
1106     0x08,0x20,
1107     0x04,0x40,
1108     0x02,0x80,
1109     0x01,0x00,
1110     0x02,0x80,
1111     0x04,0x40,
1112     0x08,0x20,
1113     0x10,0x10,
1114     0x20,0x08,
1115     0x40,0x04,
1116     0x80,0x02, // CROSS 15x15 = 3.0
1117
1118     0x80,0x00, 0x80,
1119     0x40,0x01, 0x00,
1120     0x20,0x02, 0x00,
1121     0x10,0x04, 0x00,
1122     0x08,0x08, 0x00,
1123     0x04,0x10, 0x00,
1124     0x02,0x20, 0x00,
1125     0x01,0x40, 0x00,
1126     0x00,0x80, 0x00,
1127     0x01,0x40, 0x00,
1128     0x02,0x20, 0x00,
1129     0x04,0x10, 0x00,
1130     0x08,0x08, 0x00,
1131     0x10,0x04, 0x00,
1132     0x20,0x02, 0x00,
1133     0x40,0x01, 0x00,
1134     0x80,0x00, 0x80, // CROSS 17x17 = 3.5
1135
1136     0x80,0x00, 0x20,
1137     0x40,0x00, 0x40,
1138     0x20,0x00, 0x80,
1139     0x10,0x01, 0x00,
1140     0x08,0x02, 0x00,
1141     0x04,0x04, 0x00,
1142     0x02,0x08, 0x00,
1143     0x01,0x10, 0x00,
1144     0x00,0xa0, 0x00,
1145     0x00,0x40, 0x00,
1146     0x00,0xa0, 0x00,
1147     0x01,0x10, 0x00,
1148     0x02,0x08, 0x00,
1149     0x04,0x04, 0x00,
1150     0x08,0x02, 0x00,
1151     0x10,0x01, 0x00,
1152     0x20,0x00, 0x80,
1153     0x40,0x00, 0x40,
1154     0x80,0x00, 0x20, // CROSS 19x19 = 4.0
1155
1156     0x80,0x00, 0x08,
1157     0x40,0x00, 0x10,
1158     0x20,0x00, 0x20,
1159     0x10,0x00, 0x40,
1160     0x08,0x00, 0x80,
1161     0x04,0x01, 0x00,
1162     0x02,0x02, 0x00,
1163     0x01,0x04, 0x00,
1164     0x00,0x88, 0x00,
1165     0x00,0x50, 0x00,
1166     0x00,0x20, 0x00,
1167     0x00,0x50, 0x00,
1168     0x00,0x88, 0x00,
1169     0x01,0x04, 0x00,
1170     0x02,0x02, 0x00,
1171     0x04,0x01, 0x00,
1172     0x08,0x00, 0x80,
1173     0x10,0x00, 0x40,
1174     0x20,0x00, 0x20,
1175     0x40,0x00, 0x10,
1176     0x80,0x00, 0x08,/* CROSS 21x21 = 4.5 */
1177
1178     0x80,0x00, 0x02,
1179     0x40,0x00, 0x04,
1180     0x20,0x00, 0x08,
1181     0x10,0x00, 0x10,
1182     0x08,0x00, 0x20,
1183     0x04,0x00, 0x40,
1184     0x02,0x00, 0x80,
1185     0x01,0x01, 0x00,
1186     0x00,0x82, 0x00,
1187     0x00,0x44, 0x00,
1188     0x00,0x28, 0x00,
1189     0x00,0x10, 0x00,
1190     0x00,0x28, 0x00,
1191     0x00,0x44, 0x00,
1192     0x00,0x82, 0x00,
1193     0x01,0x01, 0x00,
1194     0x02,0x00, 0x80,
1195     0x04,0x00, 0x40,
1196     0x08,0x00, 0x20,
1197     0x10,0x00, 0x10,
1198     0x20,0x00, 0x08,
1199     0x40,0x00, 0x04,
1200     0x80,0x00, 0x02, // CROSS 23x23 = 5.0
1201
1202     0x80,0x00, 0x00,0x80,
1203     0x40,0x00, 0x01,0x00,
1204     0x20,0x00, 0x02,0x00,
1205     0x10,0x00, 0x04,0x00,
1206     0x08,0x00, 0x08,0x00,
1207     0x04,0x00, 0x10,0x00,
1208     0x02,0x00, 0x20,0x00,
1209     0x01,0x00, 0x40,0x00,
1210     0x00,0x80, 0x80,0x00,
1211     0x00,0x41, 0x00,0x00,
1212     0x00,0x22, 0x00,0x00,
1213     0x00,0x14, 0x00,0x00,
1214     0x00,0x08, 0x00,0x00,
1215     0x00,0x14, 0x00,0x00,
1216     0x00,0x22, 0x00,0x00,
1217     0x00,0x41, 0x00,0x00,
1218     0x00,0x80, 0x80,0x00,
1219     0x01,0x00, 0x40,0x00,
1220     0x02,0x00, 0x20,0x00,
1221     0x04,0x00, 0x10,0x00,
1222     0x08,0x00, 0x08,0x00,
1223     0x10,0x00, 0x04,0x00,
1224     0x20,0x00, 0x02,0x00,
1225     0x40,0x00, 0x01,0x00,
1226     0x80,0x00, 0x00,0x80, // CROSS 25x25 = 5.5
1227
1228     0x80,0x00, 0x00,0x20,
1229     0x40,0x00, 0x00,0x40,
1230     0x20,0x00, 0x00,0x80,
1231     0x10,0x00, 0x01,0x00,
1232     0x08,0x00, 0x02,0x00,
1233     0x04,0x00, 0x04,0x00,
1234     0x02,0x00, 0x08,0x00,
1235     0x01,0x00, 0x10,0x00,
1236     0x00,0x80, 0x20,0x00,
1237     0x00,0x40, 0x40,0x00,
1238     0x00,0x20, 0x80,0x00,
1239     0x00,0x11, 0x00,0x00,
1240     0x00,0x0a, 0x00,0x00,
1241     0x00,0x04, 0x00,0x00,
1242     0x00,0x0a, 0x00,0x00,
1243     0x00,0x11, 0x00,0x00,
1244     0x00,0x20, 0x80,0x00,
1245     0x00,0x40, 0x40,0x00,
1246     0x00,0x80, 0x20,0x00,
1247     0x01,0x00, 0x10,0x00,
1248     0x02,0x00, 0x08,0x00,
1249     0x04,0x00, 0x04,0x00,
1250     0x08,0x00, 0x02,0x00,
1251     0x10,0x00, 0x01,0x00,
1252     0x20,0x00, 0x00,0x80,
1253     0x40,0x00, 0x00,0x40,
1254     0x80,0x00, 0x00,0x20, // CROSS 27x27 = 6.0
1255
1256     0x00,0x00, 0x00,0x00,
1257     0x00,0x00, 0x00,0x00,
1258     0x20,0x00, 0x00,0x04,
1259     0x10,0x00, 0x00,0x08,
1260     0x08,0x00, 0x00,0x10,
1261     0x04,0x00, 0x00,0x20,
1262     0x02,0x00, 0x00,0x40,
1263     0x01,0x00, 0x00,0x80,
1264     0x00,0x80, 0x01,0x00,
1265     0x00,0x40, 0x02,0x00,
1266     0x00,0x20, 0x04,0x00,
1267     0x00,0x10, 0x08,0x00,
1268     0x00,0x08, 0x10,0x00,
1269     0x00,0x04, 0x20,0x00,
1270     0x00,0x02, 0x40,0x00,
1271     0x00,0x01, 0x80,0x00,
1272     0x00,0x01, 0x80,0x00,
1273     0x00,0x02, 0x40,0x00,
1274     0x00,0x04, 0x20,0x00,
1275     0x00,0x08, 0x10,0x00,
1276     0x00,0x10, 0x08,0x00,
1277     0x00,0x20, 0x04,0x00,
1278     0x00,0x40, 0x02,0x00,
1279     0x00,0x80, 0x01,0x00,
1280     0x01,0x00, 0x00,0x80,
1281     0x02,0x00, 0x00,0x40,
1282     0x04,0x00, 0x00,0x20,
1283     0x08,0x00, 0x00,0x10,
1284     0x10,0x00, 0x00,0x08,
1285     0x20,0x00, 0x00,0x04,
1286     0x00,0x00, 0x00,0x00,
1287     0x00,0x00, 0x00,0x00, // CROSS 32x32 = 6.5
1288
1289     0x00,0x00, 0x00,0x00,
1290     0x40,0x00, 0x00,0x02,
1291     0x20,0x00, 0x00,0x04,
1292     0x10,0x00, 0x00,0x08,
1293     0x08,0x00, 0x00,0x10,
1294     0x04,0x00, 0x00,0x20,
1295     0x02,0x00, 0x00,0x40,
1296     0x01,0x00, 0x00,0x80,
1297     0x00,0x80, 0x01,0x00,
1298     0x00,0x40, 0x02,0x00,
1299     0x00,0x20, 0x04,0x00,
1300     0x00,0x10, 0x08,0x00,
1301     0x00,0x08, 0x10,0x00,
1302     0x00,0x04, 0x20,0x00,
1303     0x00,0x02, 0x40,0x00,
1304     0x00,0x01, 0x80,0x00,
1305     0x00,0x01, 0x80,0x00,
1306     0x00,0x02, 0x40,0x00,
1307     0x00,0x04, 0x20,0x00,
1308     0x00,0x08, 0x10,0x00,
1309     0x00,0x10, 0x08,0x00,
1310     0x00,0x20, 0x04,0x00,
1311     0x00,0x40, 0x02,0x00,
1312     0x00,0x80, 0x01,0x00,
1313     0x01,0x00, 0x00,0x80,
1314     0x02,0x00, 0x00,0x40,
1315     0x04,0x00, 0x00,0x20,
1316     0x08,0x00, 0x00,0x10,
1317     0x10,0x00, 0x00,0x08,
1318     0x20,0x00, 0x00,0x04,
1319     0x40,0x00, 0x00,0x02,
1320     0x00,0x00, 0x00,0x00  // CROSS 32x32 = 7.0
1321 };
1322
1323 // =======================================================================
1324 // function : GetMarkerBitMapArray
1325 // purpose  : Returns a parameters for the marker of the specified
1326 //            type and scale.
1327 // =======================================================================
1328 void GetMarkerBitMapParam (const Aspect_TypeOfMarker theMarkerType,
1329                            const Standard_ShortReal& theScale,
1330                            Standard_Integer& theWidth,
1331                            Standard_Integer& theHeight,
1332                            Standard_Integer& theOffset,
1333                            Standard_Integer& theNumOfBytes)
1334 {
1335   const Standard_Integer aType = (Standard_Integer )((theMarkerType > Aspect_TOM_O) ? Aspect_TOM_O : theMarkerType);
1336   const Standard_Real anIndex = (Standard_Real )(TEL_NO_OF_SIZES - 1) * (theScale - (Standard_Real )TEL_PM_START_SIZE)
1337                               / (Standard_Real )(TEL_PM_END_SIZE - TEL_PM_START_SIZE);
1338   Standard_Integer anId = (Standard_Integer )(anIndex + 0.5);
1339   if (anId < 0)
1340   {
1341     anId = 0;
1342   }
1343   else if (anId >= TEL_NO_OF_SIZES)
1344   {
1345     anId = TEL_NO_OF_SIZES - 1;
1346   }
1347
1348   theWidth  = (Standard_Integer )arrPMFontInfo[aType][anId].width;
1349   theHeight = (Standard_Integer )arrPMFontInfo[aType][anId].height;
1350   theOffset = arrPMFontInfo[aType][anId].offset;
1351   const Standard_Integer aNumOfBytesInRow = theWidth / 8 + (theWidth % 8 ? 1 : 0);
1352   theNumOfBytes = theHeight * aNumOfBytesInRow;
1353 }
1354
1355 // =======================================================================
1356 // function : GetTextureImage
1357 // purpose  : Returns a marker image for the marker of the specified
1358 //            type and scale.
1359 // =======================================================================
1360 Handle(Graphic3d_MarkerImage) GetTextureImage (const Aspect_TypeOfMarker theMarkerType,
1361                                                const Standard_ShortReal& theScale)
1362 {
1363   Standard_Integer aWidth, aHeight, anOffset, aNumOfBytes;
1364   GetMarkerBitMapParam (theMarkerType, theScale, aWidth, aHeight, anOffset, aNumOfBytes);
1365
1366   Handle(TColStd_HArray1OfByte) aBitMap = new TColStd_HArray1OfByte (0, aNumOfBytes - 1);
1367   for (Standard_Integer anIter = 0; anIter < aNumOfBytes; anIter++)
1368   {
1369     aBitMap->ChangeValue (anIter) = OpenGl_AspectMarker_myMarkerRaster[anOffset + anIter];
1370   }
1371
1372   Handle(Graphic3d_MarkerImage) aTexture = new Graphic3d_MarkerImage (aBitMap, aWidth, aHeight);
1373   return aTexture;
1374 }
1375
1376 // =======================================================================
1377 // function : MergeImages
1378 // purpose  : Merge two image pixmap into one. Used for creating image for
1379 //            following markers: Aspect_TOM_O_POINT, Aspect_TOM_O_PLUS,
1380 //            Aspect_TOM_O_STAR, Aspect_TOM_O_X, Aspect_TOM_RING1,
1381 //            Aspect_TOM_RING2, Aspect_TOM_RING3
1382 // =======================================================================
1383 Handle(Image_PixMap) MergeImages (const Handle(Image_PixMap)& theImage1,
1384                                   const Handle(Image_PixMap)& theImage2)
1385 {
1386   if (theImage1.IsNull() && theImage2.IsNull())
1387   {
1388     return Handle(Image_PixMap)();
1389   }
1390
1391   Handle(Image_PixMap) aResultImage = new Image_PixMap();
1392
1393   Standard_Integer aWidth1 (0), aHeight1 (0);
1394   if (!theImage1.IsNull())
1395   {
1396     aWidth1  = (Standard_Integer )theImage1->Width();
1397     aHeight1 = (Standard_Integer )theImage1->Height();
1398   }
1399
1400   Standard_Integer aWidth2 (0), aHeight2 (0);
1401   if (!theImage2.IsNull())
1402   {
1403     aWidth2  = (Standard_Integer )theImage2->Width();
1404     aHeight2 = (Standard_Integer )theImage2->Height();
1405   }
1406
1407   const Standard_Integer aMaxWidth  = Max (aWidth1,   aWidth2);
1408   const Standard_Integer aMaxHeight = Max (aHeight1,  aHeight2);
1409   const Standard_Integer aSize      = Max (aMaxWidth, aMaxHeight);
1410
1411   aResultImage->InitZero (Image_PixMap::ImgGray, aSize, aSize);
1412
1413   if (!theImage1.IsNull())
1414   {
1415     const Standard_Integer aXOffset1  = Abs (aWidth1  - aMaxWidth)  / 2;
1416     const Standard_Integer anYOffset1 = Abs (aHeight1 - aMaxHeight) / 2;
1417     for (Standard_Integer anY = 0; anY < aHeight1; anY++)
1418     {
1419       Standard_Byte* anImageLine = theImage1->ChangeRow (anY);
1420       Standard_Byte* aResultImageLine = aResultImage->ChangeRow (anYOffset1 + anY);
1421       for (Standard_Integer aX = 0; aX < aWidth1; aX++)
1422       {
1423         aResultImageLine[aXOffset1 + aX] |= anImageLine[aX];
1424       }
1425     }
1426   }
1427
1428   if (!theImage2.IsNull())
1429   {
1430     const Standard_Integer aXOffset2  = Abs (aWidth2  - aMaxWidth)  / 2;
1431     const Standard_Integer anYOffset2 = Abs (aHeight2 - aMaxHeight) / 2;
1432     for (Standard_Integer anY = 0; anY < aHeight2; anY++)
1433     {
1434       Standard_Byte* anImageLine = theImage2->ChangeRow (anY);
1435       Standard_Byte* aResultImageLine = aResultImage->ChangeRow (anYOffset2 + anY);
1436       for (Standard_Integer aX = 0; aX < aWidth2; aX++)
1437       {
1438         aResultImageLine[aXOffset2 + aX] |= anImageLine[aX];
1439       }
1440     }
1441   }
1442
1443   return aResultImage;
1444 }
1445
1446 // =======================================================================
1447 // function : OpenGl_AspectMarker
1448 // purpose  :
1449 // =======================================================================
1450 OpenGl_AspectMarker::OpenGl_AspectMarker()
1451  : myColor (myDefaultColor),
1452    myType  (Aspect_TOM_PLUS),
1453    myScale (1.0f),
1454    myMarkerSize (1.0f),
1455    myMarkerImage(),
1456    myShaderProgram()
1457 {}
1458
1459 // =======================================================================
1460 // function : SetAspect
1461 // purpose  :
1462 // =======================================================================
1463 void OpenGl_AspectMarker::SetAspect (const CALL_DEF_CONTEXTMARKER& theAspect)
1464 {
1465   myColor.rgb[0] = (float )theAspect.Color.r;
1466   myColor.rgb[1] = (float )theAspect.Color.g;
1467   myColor.rgb[2] = (float )theAspect.Color.b;
1468   myColor.rgb[3] = 1.0f;
1469   myMarkerImage  = theAspect.MarkerImage;
1470   myType         = theAspect.MarkerType;
1471   myScale = myMarkerSize = theAspect.Scale;
1472   myShaderProgram = theAspect.ShaderProgram;
1473
1474   // update sprite resource bindings
1475   TCollection_AsciiString aSpriteKey  = THE_EMPTY_KEY;
1476   TCollection_AsciiString aSpriteAKey = THE_EMPTY_KEY;
1477   myResources.SpriteKeys (myMarkerImage, myType, myScale, myColor, aSpriteKey, aSpriteAKey);
1478
1479   if (aSpriteKey.IsEmpty() || myResources.SpriteKey != aSpriteKey)
1480   {
1481     myResources.ResetSpriteReadiness();
1482   }
1483   if (aSpriteAKey.IsEmpty() || myResources.SpriteAKey != aSpriteAKey)
1484   {
1485     myResources.ResetSpriteReadiness();
1486   }
1487
1488   // update shader program resource bindings
1489   const TCollection_AsciiString& aShaderKey = myShaderProgram.IsNull() ? THE_EMPTY_KEY : myShaderProgram->GetId();
1490
1491   if (aShaderKey.IsEmpty() || myResources.ShaderProgramId != aShaderKey)
1492   {
1493     myResources.ResetShaderReadiness();
1494   }
1495 }
1496
1497 // =======================================================================
1498 // function : Render
1499 // purpose  :
1500 // =======================================================================
1501 void OpenGl_AspectMarker::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
1502 {
1503   theWorkspace->SetAspectMarker (this);
1504 }
1505
1506 // =======================================================================
1507 // function : Release
1508 // purpose  :
1509 // =======================================================================
1510 void OpenGl_AspectMarker::Release (const Handle(OpenGl_Context)& theCtx)
1511 {
1512   if (!myResources.Sprite.IsNull())
1513   {
1514     if (!theCtx.IsNull())
1515     {
1516       if (myResources.SpriteKey.IsEmpty())
1517       {
1518         theCtx->DelayedRelease (myResources.Sprite);
1519         theCtx->DelayedRelease (myResources.SpriteA);
1520       }
1521       else
1522       {
1523         myResources.Sprite.Nullify(); // we need nullify all handles before ReleaseResource() call
1524         myResources.SpriteA.Nullify();
1525         theCtx->ReleaseResource (myResources.SpriteKey,  Standard_True);
1526         theCtx->ReleaseResource (myResources.SpriteAKey, Standard_True);
1527       }
1528     }
1529     myResources.Sprite.Nullify();
1530     myResources.SpriteA.Nullify();
1531   }
1532   myResources.SpriteKey.Clear();
1533   myResources.SpriteAKey.Clear();
1534   myResources.ResetSpriteReadiness();
1535
1536   if (!myResources.ShaderProgram.IsNull() && !theCtx.IsNull())
1537   {
1538     theCtx->ShaderManager()->Unregister (myResources.ShaderProgramId,
1539                                          myResources.ShaderProgram);
1540   }
1541   myResources.ShaderProgramId.Clear();
1542   myResources.ResetShaderReadiness();
1543 }
1544
1545 // =======================================================================
1546 // function : BuildSprites
1547 // purpose  :
1548 // =======================================================================
1549 void OpenGl_AspectMarker::Resources::BuildSprites (const Handle(OpenGl_Workspace)& theWorkspace,
1550                                                    const Handle(Graphic3d_MarkerImage)& theMarkerImage,
1551                                                    const Aspect_TypeOfMarker theType,
1552                                                    const Standard_ShortReal theScale,
1553                                                    const TEL_COLOUR& theColor,
1554                                                    Standard_ShortReal& theMarkerSize)
1555 {
1556   const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
1557
1558   // generate key for shared resource
1559   TCollection_AsciiString aNewKey  = THE_EMPTY_KEY;
1560   TCollection_AsciiString aNewKeyA = THE_EMPTY_KEY;
1561   SpriteKeys (theMarkerImage, theType, theScale, theColor, aNewKey, aNewKeyA);
1562
1563   // release old shared resources
1564   const Standard_Boolean aNewResource = aNewKey.IsEmpty() || SpriteKey != aNewKey;
1565   if (aNewResource)
1566   {
1567     if (!Sprite.IsNull())
1568     {
1569       if (SpriteKey.IsEmpty())
1570       {
1571         aContext->DelayedRelease (Sprite);
1572         Sprite.Nullify();
1573       }
1574       else
1575       {
1576         Sprite.Nullify(); // we need nullify all handles before ReleaseResource() call
1577         aContext->ReleaseResource (SpriteKey, Standard_True);
1578       }
1579     }
1580     SpriteKey = aNewKey;
1581   }
1582   if (aNewKeyA.IsEmpty() || SpriteAKey != aNewKeyA)
1583   {
1584     if (!SpriteA.IsNull())
1585     {
1586       if (SpriteAKey.IsEmpty())
1587       {
1588         aContext->DelayedRelease (SpriteA);
1589         SpriteA.Nullify();
1590       }
1591       else
1592       {
1593         SpriteA.Nullify(); // we need nullify all handles before ReleaseResource() call
1594         aContext->ReleaseResource (SpriteAKey, Standard_True);
1595       }
1596     }
1597     SpriteAKey = aNewKeyA;
1598   }
1599   if (theType == Aspect_TOM_POINT
1600    || !aNewResource
1601    || (theType == Aspect_TOM_USERDEFINED && theMarkerImage.IsNull()))
1602   {
1603     // nothing to do - just simple point
1604     return;
1605   }
1606
1607   if (!aNewKey.IsEmpty()
1608    && aContext->GetResource<Handle(OpenGl_PointSprite)> (aNewKeyA, SpriteA) // alpha sprite could be shared
1609    && aContext->GetResource<Handle(OpenGl_PointSprite)> (aNewKey,  Sprite))
1610   {
1611     // reuse shared resource
1612     if (!Sprite->IsDisplayList())
1613     {
1614       theMarkerSize = Standard_ShortReal (Max (Sprite->SizeX(), Sprite->SizeY()));
1615     }
1616     return;
1617   }
1618
1619   const bool hadAlreadyAlpha = !SpriteA.IsNull();
1620   if (!hadAlreadyAlpha)
1621   {
1622     SpriteA = new OpenGl_PointSprite();
1623   }
1624   Sprite  = new OpenGl_PointSprite();
1625   if (!aNewKey.IsEmpty())
1626   {
1627     aContext->ShareResource (aNewKey,  Sprite);
1628     if (!hadAlreadyAlpha)
1629     {
1630       aContext->ShareResource (aNewKeyA, SpriteA);
1631     }
1632   }
1633
1634   if (!aContext.IsNull()
1635    &&  aContext->IsGlGreaterEqual (2, 0)
1636    && !aContext->caps->pntSpritesDisable)
1637   {
1638     // Creating texture resource for using it with point sprites
1639     Handle(Graphic3d_MarkerImage) aNewMarkerImage;
1640     Handle(Image_PixMap) anImage, anImageA;
1641
1642     if (theType == Aspect_TOM_USERDEFINED && !theMarkerImage.IsNull())
1643     {
1644       aNewMarkerImage = theMarkerImage;
1645       anImage = aNewMarkerImage->GetImage();
1646     }
1647     else
1648     {
1649       // Creating image from default bitmap
1650       Handle(TColStd_HArray1OfByte) aBitMap;
1651       Handle(Graphic3d_MarkerImage) aMarkerImage1, aMarkerImage2;
1652
1653       const Standard_ShortReal aDelta = 0.1F;
1654       Standard_ShortReal aScale = theScale;
1655       Standard_ShortReal aLimit = 0.0F;
1656
1657       switch (theType)
1658       {
1659         case Aspect_TOM_O_POINT:
1660         {
1661           const Standard_Integer aSize = theScale > 7 ? 7 : (Standard_Integer )(theScale + 0.5F);
1662           const Standard_Integer aNumOfBytes = (aSize / 8 + (aSize % 8 ? 1 : 0)) * aSize;
1663           aBitMap = new TColStd_HArray1OfByte (0, aNumOfBytes - 1);
1664           for (Standard_Integer anIter = 0; anIter < aBitMap->Length(); anIter++)
1665           {
1666             aBitMap->SetValue (anIter, 255);
1667           }
1668           aMarkerImage2 = new Graphic3d_MarkerImage (aBitMap, aSize, aSize);
1669         }
1670         case Aspect_TOM_O_PLUS:
1671         case Aspect_TOM_O_STAR:
1672         case Aspect_TOM_O_X:
1673         {
1674           // For this type of markers we merge two base bitmaps into one
1675           // For example Aspect_TOM_O_PLUS = Aspect_TOM_O + Aspect_TOM_PLUS
1676           aMarkerImage1 = GetTextureImage (Aspect_TOM_O, theScale);
1677           if (theType != Aspect_TOM_O_POINT)
1678           {
1679             aMarkerImage2 = GetTextureImage (Aspect_TypeOfMarker (theType - Aspect_TOM_O_POINT), theScale);
1680           }
1681           anImage = MergeImages (aMarkerImage1->GetImage(), aMarkerImage2->GetImage());
1682           aNewMarkerImage = new Graphic3d_MarkerImage (anImage);
1683           break;
1684         }
1685         case Aspect_TOM_RING1:
1686           if (aLimit == 0.0f) aLimit = aScale * 0.2f;
1687         case Aspect_TOM_RING2:
1688           if (aLimit == 0.0f) aLimit = aScale * 0.5f;
1689         case Aspect_TOM_RING3:
1690         {
1691           if (aLimit == 0.0f) aLimit = aScale * 0.8f;
1692           for (; aScale > aLimit && aScale >= 1.0f; aScale -= aDelta)
1693           {
1694             anImage = MergeImages (anImage, GetTextureImage (Aspect_TOM_O, aScale)->GetImage());
1695           }
1696           aNewMarkerImage = new Graphic3d_MarkerImage (anImage);
1697           break;
1698         }
1699         case Aspect_TOM_BALL:
1700         {
1701           Standard_Integer aWidth, aHeight, anOffset, aNumOfBytes;
1702           GetMarkerBitMapParam (Aspect_TOM_O, aScale, aWidth, aHeight, anOffset, aNumOfBytes);
1703
1704           const Standard_ShortReal aDelta = 0.1f;
1705           NCollection_Vec4<Standard_Real> aColor (Standard_Real (theColor.rgb[0]),
1706                                                   Standard_Real (theColor.rgb[1]),
1707                                                   Standard_Real (theColor.rgb[2]),
1708                                                   Standard_Real (theColor.rgb[3]));
1709
1710           const Standard_Integer aSize = Max (aWidth + 2, aHeight + 2); // includes extra margin
1711           anImage  = new Image_PixMap();
1712           anImageA = new Image_PixMap();
1713           anImage ->InitZero (Image_PixMap::ImgBGRA, aSize, aSize);
1714           anImageA->InitZero (Image_PixMap::ImgGray, aSize, aSize);
1715           Image_PixMapData<Image_ColorBGRA>& aDataBGRA = anImage->EditData<Image_ColorBGRA>();
1716           Image_PixMapData<Standard_Byte>&   aDataGray = anImageA->EditData<Standard_Byte>();
1717
1718           // we draw a set of circles
1719           Image_ColorBGRA aColor32;
1720           aColor32.a() = 255;
1721           Standard_Real aHLS[3];
1722           while (aScale >= 1.0f)
1723           {
1724             Quantity_Color::RgbHls (aColor.r(), aColor.g(), aColor.b(), aHLS[0], aHLS[1], aHLS[2]);
1725             aHLS[2] *= 0.95; // 5% saturation change
1726             Quantity_Color::HlsRgb (aHLS[0], aHLS[1], aHLS[2], aColor.r(), aColor.g(), aColor.b());
1727             aColor32.r() = Standard_Byte(255.0 * aColor.r());
1728             aColor32.g() = Standard_Byte(255.0 * aColor.g());
1729             aColor32.b() = Standard_Byte(255.0 * aColor.b());
1730
1731             const Handle(Graphic3d_MarkerImage) aMarker = GetTextureImage (Aspect_TOM_O, aScale);
1732             const Handle(Image_PixMap)& aCircle = aMarker->GetImage();
1733
1734             const Standard_Size aDiffX = (aDataBGRA.SizeX() - aCircle->SizeX()) / 2;
1735             const Standard_Size aDiffY = (aDataBGRA.SizeY() - aCircle->SizeY()) / 2;
1736             for (Standard_Size aRow = 0; aRow < aCircle->SizeY(); ++aRow)
1737             {
1738               const Standard_Byte* aRowData = aCircle->Row (aRow);
1739               for (Standard_Size aCol = 0; aCol < aCircle->SizeX(); ++aCol)
1740               {
1741                 if (aRowData[aCol] != 0)
1742                 {
1743                   aDataBGRA.ChangeValue (aDiffX + aRow, aDiffY + aCol) = aColor32;
1744                   aDataGray.ChangeValue (aDiffX + aRow, aDiffY + aCol) = 255;
1745                 }
1746               }
1747             }
1748             aScale -= aDelta;
1749           }
1750           break;
1751         }
1752         default:
1753         {
1754           aNewMarkerImage = GetTextureImage (theType, theScale);
1755           anImage = aNewMarkerImage->GetImage();
1756           break;
1757         }
1758       }
1759     }
1760
1761     theMarkerSize = Max ((Standard_ShortReal )anImage->Width(),(Standard_ShortReal )anImage->Height());
1762
1763     Sprite->Init (aContext, *anImage.operator->(), Graphic3d_TOT_2D);
1764     if (!hadAlreadyAlpha)
1765     {
1766       if (anImageA.IsNull()
1767        && Sprite->GetFormat() != GL_ALPHA8
1768        && !aNewMarkerImage.IsNull())
1769       {
1770         anImageA = aNewMarkerImage->GetImageAlpha();
1771       }
1772       if (!anImageA.IsNull())
1773       {
1774         SpriteA->Init (aContext, *anImageA.operator->(), Graphic3d_TOT_2D);
1775       }
1776     }
1777   }
1778   else
1779   {
1780     // Creating list with bitmap for using it in compatibility mode
1781     GLuint aBitmapList = glGenLists (1);
1782     Sprite->SetDisplayList (aContext, aBitmapList);
1783
1784     Standard_Integer aWidth, aHeight, anOffset, aNumOfBytes;
1785     if (theType == Aspect_TOM_USERDEFINED && !theMarkerImage.IsNull())
1786     {
1787       // Reading user defined marker
1788       Handle(TColStd_HArray1OfByte) aBitMap = theMarkerImage->GetBitMapArray();
1789       Standard_Byte* aBitMapArray = new Standard_Byte[aBitMap->Length()];
1790       theMarkerImage->GetTextureSize (aWidth, aHeight);
1791
1792       // We should pass bitmap to glBitmap with reversed line order as it draws it from
1793       // bottom to top
1794       const Standard_Integer aNumOfBytesInRow = aWidth / 8 + (aWidth % 8 ? 1 : 0);
1795       const Standard_Integer anUpperIndex = aBitMap->Upper();
1796       for (Standard_Integer aRow = 0; aRow < aHeight; aRow++)
1797       {
1798         for (Standard_Integer aByteIter = 0; aByteIter < aNumOfBytesInRow; aByteIter++)
1799         {
1800           aBitMapArray[aRow * aNumOfBytesInRow + aByteIter] =
1801             aBitMap->Value (anUpperIndex + 1 - (aRow + 1) * aNumOfBytesInRow + aByteIter);
1802         }
1803       }
1804
1805       if (aBitMapArray != NULL)
1806       {
1807         glNewList (aBitmapList, GL_COMPILE);
1808         glBitmap ((GLsizei )aWidth, (GLsizei )aHeight, (GLfloat )(0.5f * aWidth), (GLfloat )(0.5f * aHeight),
1809                   0.f, 0.f, (const GLubyte* )aBitMapArray);
1810         glEndList();
1811       }
1812     }
1813     else
1814     {
1815       // Creating list for default marker
1816       const Standard_ShortReal aDelta = 0.1f;
1817       Standard_ShortReal aScale = theScale;
1818       Standard_ShortReal aLimit = 0.0f;
1819
1820       glNewList (aBitmapList, GL_COMPILE);
1821       switch (theType)
1822       {
1823         case Aspect_TOM_O_PLUS:
1824         case Aspect_TOM_O_STAR:
1825         case Aspect_TOM_O_X:
1826         {
1827           // For this type of markers we merge two base bitmaps into one
1828           // For example Aspect_TOM_O_PLUS = Aspect_TOM_O + Aspect_TOM_PLUS
1829           GetMarkerBitMapParam (Aspect_TOM_O, theScale, aWidth, aHeight, anOffset, aNumOfBytes);
1830           glBitmap ((GLsizei )aWidth, (GLsizei )aHeight, (GLfloat )(0.5f * aWidth), (GLfloat )(0.5f * aHeight),
1831                     0.f, 0.f, (const GLubyte* )&OpenGl_AspectMarker_myMarkerRaster[anOffset]);
1832           GetMarkerBitMapParam (Aspect_TypeOfMarker (theType - Aspect_TOM_O_POINT), theScale, aWidth, aHeight, anOffset, aNumOfBytes);
1833           glBitmap ((GLsizei )aWidth, (GLsizei )aHeight, (GLfloat )(0.5f * aWidth), (GLfloat )(0.5f * aHeight),
1834                     0.f, 0.f, (const GLubyte* )&OpenGl_AspectMarker_myMarkerRaster[anOffset]);
1835           break;
1836         }
1837         case Aspect_TOM_BALL:
1838         {
1839           const Standard_ShortReal aDelta = 0.1f;
1840           NCollection_Vec4<Standard_Real> aColor (Standard_Real (theColor.rgb[0]),
1841                                                   Standard_Real (theColor.rgb[1]),
1842                                                   Standard_Real (theColor.rgb[2]),
1843                                                   Standard_Real (theColor.rgb[3]));
1844
1845           // we draw a set of circles
1846           while (aScale >= 1.0f)
1847           {
1848             Standard_Real aHLS[3];
1849             Quantity_Color::RgbHls (aColor.r(), aColor.g(), aColor.b(), aHLS[0], aHLS[1], aHLS[2]);
1850             // 5% saturation change
1851             aHLS[2] *= 0.95;
1852             Quantity_Color::HlsRgb (aHLS[0], aHLS[1], aHLS[2], aColor.r(), aColor.g(), aColor.b());
1853
1854             glColor4dv (aColor);
1855             GetMarkerBitMapParam (Aspect_TOM_O, aScale, aWidth, aHeight, anOffset, aNumOfBytes);
1856             glBitmap ((GLsizei )aWidth, (GLsizei )aHeight, 0.5f * GLfloat(aWidth), 0.5f * GLfloat(aHeight),
1857                       0.0f, 0.0f, (const GLubyte* )&OpenGl_AspectMarker_myMarkerRaster[anOffset]);
1858
1859             aScale -= aDelta;
1860           }
1861           break;
1862         }
1863         case Aspect_TOM_RING1:
1864           if (aLimit == 0.0f) aLimit = aScale * 0.2f;
1865         case Aspect_TOM_RING2:
1866           if (aLimit == 0.0f) aLimit = aScale * 0.5f;
1867         case Aspect_TOM_RING3:
1868         {
1869           if (aLimit == 0.0f) aLimit = aScale * 0.8f;
1870           for (; aScale > aLimit && aScale >= 1.0f; aScale -= aDelta)
1871           {
1872             GetMarkerBitMapParam (Aspect_TOM_O, aScale, aWidth, aHeight, anOffset, aNumOfBytes);
1873             glBitmap ((GLsizei )aWidth, (GLsizei )aHeight, 0.5f * GLfloat(aWidth), 0.5f * GLfloat(aHeight),
1874                       0.0f, 0.0f, (const GLubyte* )&OpenGl_AspectMarker_myMarkerRaster[anOffset]);
1875           }
1876           break;
1877         }
1878         default:
1879         {
1880           GetMarkerBitMapParam (theType, theScale, aWidth, aHeight, anOffset, aNumOfBytes);
1881           glBitmap ((GLsizei )aWidth, (GLsizei )aHeight, 0.5f * GLfloat(aWidth), 0.5f * GLfloat(aHeight),
1882                     0.0f, 0.0f, (const GLubyte* )&OpenGl_AspectMarker_myMarkerRaster[anOffset]);
1883           break;
1884         }
1885       }
1886       glEndList();
1887     }
1888   }
1889 }
1890
1891 // =======================================================================
1892 // function : BuildShader
1893 // purpose  :
1894 // =======================================================================
1895 void OpenGl_AspectMarker::Resources::BuildShader (const Handle(OpenGl_Workspace)&        theWS,
1896                                                   const Handle(Graphic3d_ShaderProgram)& theShader)
1897 {
1898   const Handle(OpenGl_Context)& aContext = theWS->GetGlContext();
1899   if (!aContext->IsGlGreaterEqual (2, 0))
1900   {
1901     return;
1902   }
1903
1904   // release old shader program resources
1905   if (!ShaderProgram.IsNull())
1906   {
1907     aContext->ShaderManager()->Unregister (ShaderProgramId, ShaderProgram);
1908     ShaderProgramId.Clear();
1909     ShaderProgram.Nullify();
1910   }
1911   if (theShader.IsNull())
1912   {
1913     return;
1914   }
1915
1916   aContext->ShaderManager()->Create (theShader, ShaderProgramId, ShaderProgram);
1917 }
1918
1919 // =======================================================================
1920 // function : resourceKeys
1921 // purpose  :
1922 // =======================================================================
1923 void OpenGl_AspectMarker::Resources::SpriteKeys (const Handle(Graphic3d_MarkerImage)& theMarkerImage,
1924                                                  const Aspect_TypeOfMarker theType,
1925                                                  const Standard_ShortReal theScale,
1926                                                  const TEL_COLOUR& theColor,
1927                                                  TCollection_AsciiString& theKey,
1928                                                  TCollection_AsciiString& theKeyA)
1929 {
1930   // generate key for shared resource
1931   if (theType == Aspect_TOM_USERDEFINED)
1932   {
1933     if (!theMarkerImage.IsNull())
1934     {
1935       theKey  = theMarkerImage->GetImageId();
1936       theKeyA = theMarkerImage->GetImageAlphaId();
1937     }
1938   }
1939   else if (theType != Aspect_TOM_POINT)
1940   {
1941     // predefined markers
1942     const Standard_Integer aScale = Standard_Integer(theScale + 0.5f);
1943     theKey  = TCollection_AsciiString ("OpenGl_AspectMarker") + theType + "_" + aScale;
1944     theKeyA = theKey + "A";
1945     if (theType == Aspect_TOM_BALL)
1946     {
1947       unsigned int aColor[3] =
1948       {
1949         (unsigned int )(255.0f * theColor.rgb[0]),
1950         (unsigned int )(255.0f * theColor.rgb[1]),
1951         (unsigned int )(255.0f * theColor.rgb[2])
1952       };
1953       char aBytes[8];
1954       sprintf (aBytes, "%02X%02X%02X", aColor[0], aColor[1], aColor[2]);
1955       theKey += aBytes;
1956     }
1957   }
1958 }