1 
2 
3 #include "tgl.h"
4 
5 #include "tconvert.h"
6 #include "tofflinegl.h"
7 #include "trop.h"
8 #include "timage_io.h"
9 #include "tcurves.h"
10 
11 #ifndef __sgi
12 #ifdef _WIN32
13 #include <cstdlib>
14 #include <GL/glut.h>
15 #elif defined(LINUX) || defined(FREEBSD)
16 #include <GL/glut.h>
17 #else
18 #include <GLUT/glut.h>
19 #endif
20 #endif
21 
22 #if defined(MACOSX) || defined(LINUX) || defined(FREEBSD)
23 #include <QGLContext>
24 #endif
25 
26 //#include "tthread.h"
27 
28 #undef SCALE_BY_GLU
29 //#undef NEW_DRAW_TEXT
30 
31 //-----------------------------------------------------------------------------
32 
33 namespace {
34 
35 // GLUquadric*  localDisk=0;
36 
37 /*
38   Find the number of slices in function of radius size.
39   \par radius of circle
40   \par size of pixel
41   \ret number of division to obtain a circle
42   */
computeSlices(double radius,double pixelSize=1.0)43 int computeSlices(double radius, double pixelSize = 1.0) {
44   if (radius < 0) return 2;
45 
46   double thetaStep;
47   double temp = pixelSize * 0.5 / radius;
48 
49   if (fabs(1.0 - temp) <= 1)
50     thetaStep = acos(1.0 - temp);
51   else
52     thetaStep = M_PI_4;
53 
54   assert(thetaStep != 0.0);
55 
56   int numberOfSlices = (int)(M_2PI / thetaStep);
57 
58   return numberOfSlices != 0 ? numberOfSlices : 2;
59 }
60 }  // end of unnamed namespace
61 
62 //-----------------------------------------------------------------------------
63 
tglGetPixelSize2()64 double tglGetPixelSize2() {
65   double mat[16];
66   glMatrixMode(GL_MODELVIEW);
67   glGetDoublev(GL_MODELVIEW_MATRIX, mat);
68 
69   double det = fabs(mat[0] * mat[5] - mat[1] * mat[4]);
70   if (det < TConsts::epsilon) det = TConsts::epsilon;
71   return 1.0 / det;
72 }
73 
74 //-----------------------------------------------------------------------------
75 
tglGetTextWidth(const std::string & s,void * font)76 double tglGetTextWidth(const std::string &s, void *font) {
77   double factor = 0.07;
78   double w      = 0;
79   for (int i = 0; i < (int)s.length(); i++) w += glutStrokeWidth(font, s[i]);
80   return w * factor;
81 }
82 
83 //-----------------------------------------------------------------------------
84 
tglDrawText(const TPointD & p,const std::string & s,void * character)85 void tglDrawText(const TPointD &p, const std::string &s, void *character) {
86 #ifndef __sgi
87   glPushMatrix();
88   glTranslated(p.x, p.y, 0);
89   double factor = 0.07;
90   glScaled(factor, factor, factor);
91   for (int i = 0; i < (int)s.size(); i++) glutStrokeCharacter(character, s[i]);
92   glPopMatrix();
93 #else
94   assert("Not Yet Implemented" && 0);
95   std::cout << s << std::endl;
96 #endif
97 }
98 
99 //-----------------------------------------------------------------------------
100 
tglDrawText(const TPointD & p,const std::wstring & s,void * character)101 void tglDrawText(const TPointD &p, const std::wstring &s, void *character) {
102 #ifndef __sgi
103   glPushMatrix();
104   glTranslated(p.x, p.y, 0);
105   double factor = 0.07;
106   glScaled(factor, factor, factor);
107   for (int i = 0; i < (int)s.size(); i++) glutStrokeCharacter(character, s[i]);
108   glPopMatrix();
109 #else
110   assert("Not Yet Implemented" && 0);
111   std::cout << s << std::endl;
112 #endif
113 }
114 
115 //-----------------------------------------------------------------------------
116 
tglDrawSegment(const TPointD & p1,const TPointD & p2)117 void tglDrawSegment(const TPointD &p1, const TPointD &p2) {
118   glBegin(GL_LINES);
119   tglVertex(p1);
120   tglVertex(p2);
121   glEnd();
122 }
123 
124 //-----------------------------------------------------------------------------
125 
tglDrawCircle(const TPointD & center,double radius)126 void tglDrawCircle(const TPointD &center, double radius) {
127   if (radius <= 0) return;
128 
129   double pixelSize = 1;
130   int slices       = 60;
131 
132   if (slices <= 0) slices = computeSlices(radius, pixelSize) >> 1;
133 
134   double step  = M_PI / slices;
135   double step2 = 2.0 * step;
136 
137   double cos_t, sin_t, cos_ts, sin_ts, t;
138 
139   glPushMatrix();
140   glTranslated(center.x, center.y, 0.0);
141   glBegin(GL_LINES);
142 
143   cos_t = radius /* *1.0*/;
144   sin_t = 0.0;
145   for (t = 0; t + step < M_PI_2; t += step2) {
146     cos_ts = radius * cos(t + step);
147     sin_ts = radius * sin(t + step);
148 
149     glVertex2f(cos_t, sin_t);
150     glVertex2f(cos_ts, sin_ts);
151 
152     glVertex2f(-cos_t, sin_t);
153     glVertex2f(-cos_ts, sin_ts);
154 
155     glVertex2f(-cos_t, -sin_t);
156     glVertex2f(-cos_ts, -sin_ts);
157 
158     glVertex2f(cos_t, -sin_t);
159     glVertex2f(cos_ts, -sin_ts);
160 
161     cos_t = cos_ts;
162     sin_t = sin_ts;
163   }
164 
165   cos_ts = 0.0;
166   sin_ts = radius /* *1.0*/;
167 
168   glVertex2f(cos_t, sin_t);
169   glVertex2f(cos_ts, sin_ts);
170 
171   glVertex2f(-cos_t, sin_t);
172   glVertex2f(-cos_ts, sin_ts);
173 
174   glVertex2f(-cos_t, -sin_t);
175   glVertex2f(-cos_ts, -sin_ts);
176 
177   glVertex2f(cos_t, -sin_t);
178   glVertex2f(cos_ts, -sin_ts);
179 
180   glEnd();
181   glPopMatrix();
182 }
183 
184 //-----------------------------------------------------------------------------
185 
tglDrawDisk(const TPointD & c,double r)186 void tglDrawDisk(const TPointD &c, double r) {
187   if (r <= 0) return;
188 
189   double pixelSize = 1;
190   int slices       = 60;
191 
192   if (slices <= 0) slices = computeSlices(r, pixelSize) >> 1;
193 
194   glPushMatrix();
195   glTranslated(c.x, c.y, 0.0);
196   GLUquadric *quadric = gluNewQuadric();
197   gluDisk(quadric, 0, r, slices, 1);
198   gluDeleteQuadric(quadric);
199   glPopMatrix();
200 }
201 
202 //-----------------------------------------------------------------------------
203 
tglDrawRect(const TRectD & rect)204 void tglDrawRect(const TRectD &rect) {
205   glBegin(GL_LINE_LOOP);
206   tglVertex(rect.getP00());
207   tglVertex(rect.getP10());
208   tglVertex(rect.getP11());
209   tglVertex(rect.getP01());
210   glEnd();
211 }
212 
213 //-----------------------------------------------------------------------------
214 
tglFillRect(const TRectD & rect)215 void tglFillRect(const TRectD &rect) {
216   glBegin(GL_POLYGON);
217   tglVertex(rect.getP00());
218   tglVertex(rect.getP10());
219   tglVertex(rect.getP11());
220   tglVertex(rect.getP01());
221   glEnd();
222 }
223 //-----------------------------------------------------------------------------
224 
tglRgbOnlyColorMask()225 void tglRgbOnlyColorMask() {
226   tglMultColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
227   tglEnableBlending(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
228 }
229 
230 //-----------------------------------------------------------------------------
231 
tglAlphaOnlyColorMask()232 void tglAlphaOnlyColorMask() {
233   tglMultColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
234   tglEnableBlending(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
235 }
236 
237 //-----------------------------------------------------------------------------
238 
tglEnableBlending(GLenum src,GLenum dst)239 void tglEnableBlending(GLenum src, GLenum dst) {
240   glEnable(GL_BLEND);
241   glBlendFunc(src, dst);
242 }
243 
244 //-----------------------------------------------------------------------------
245 
tglEnableLineSmooth(bool enable,double lineSize)246 void tglEnableLineSmooth(bool enable, double lineSize) {
247   if (enable) {
248     glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
249     glEnable(GL_LINE_SMOOTH);
250     glLineWidth(lineSize);
251   } else
252     glDisable(GL_LINE_SMOOTH);
253 }
254 
255 //-----------------------------------------------------------------------------
256 
tglEnablePointSmooth(double pointSize)257 void tglEnablePointSmooth(double pointSize) {
258   glEnable(GL_BLEND);
259   glPointSize(pointSize);
260 }
261 
262 //-----------------------------------------------------------------------------
263 
tglGetColorMask(GLboolean & red,GLboolean & green,GLboolean & blue,GLboolean & alpha)264 void tglGetColorMask(GLboolean &red, GLboolean &green, GLboolean &blue,
265                      GLboolean &alpha) {
266   GLboolean channels[4];
267   glGetBooleanv(GL_COLOR_WRITEMASK, &channels[0]);
268   red = channels[0], green = channels[1], blue = channels[2],
269   alpha = channels[3];
270 }
271 
272 //-----------------------------------------------------------------------------
273 
tglMultColorMask(GLboolean red,GLboolean green,GLboolean blue,GLboolean alpha)274 void tglMultColorMask(GLboolean red, GLboolean green, GLboolean blue,
275                       GLboolean alpha) {
276   GLboolean channels[4];
277   glGetBooleanv(GL_COLOR_WRITEMASK, &channels[0]);
278   glColorMask(red && channels[0], green && channels[1], blue && channels[2],
279               alpha && channels[3]);
280 }
281 
282 //============================================================================
283 
284 namespace {
285 //============================================================================
286 
287 class GlFontManager {
288   GlFontManager();
289 
290 public:
291   ~GlFontManager();
292   static GlFontManager *instance();
293   bool setFont(void *font = GLUT_BITMAP_TIMES_ROMAN_10);
294   void drawText(/*const TRectD bBox,*/
295                 std::wstring wtext /*,
296                 TDimensionD scale = TDimensionD(1.0, 1.0)*/);
297 
298 private:
299   static GlFontManager *m_instance;
300 
301   //       font    font_height
302   //         |       |
303   std::map<void *, double> m_fonts;
304   std::vector<TRectD> m_charsBBox;
305   void *m_currentFont;
306   TRaster32P m_fontTexture;
307   GLuint m_base;
308 };
309 
310 //----------------------------------------------------------------------------
311 
312 GlFontManager *GlFontManager::m_instance = 0L;
313 
314 //----------------------------------------------------------------------------
315 
GlFontManager()316 GlFontManager::GlFontManager() : m_currentFont(0L), m_base(0) {
317   m_fonts.insert(std::make_pair(GLUT_BITMAP_8_BY_13, 13.0));
318   m_fonts.insert(std::make_pair(GLUT_BITMAP_9_BY_15, 15.0));
319   m_fonts.insert(std::make_pair(GLUT_BITMAP_TIMES_ROMAN_10, 10.0));
320   m_fonts.insert(std::make_pair(GLUT_BITMAP_TIMES_ROMAN_24, 24.0));
321   m_fonts.insert(std::make_pair(GLUT_BITMAP_HELVETICA_10, 10.0));
322   m_fonts.insert(std::make_pair(GLUT_BITMAP_HELVETICA_12, 12.0));
323   m_fonts.insert(std::make_pair(GLUT_BITMAP_HELVETICA_18, 18.0));
324   bool ok = setFont();
325   assert(ok);
326 }
327 
328 //----------------------------------------------------------------------------
329 
~GlFontManager()330 GlFontManager::~GlFontManager() { m_instance = 0L; }
331 
332 //----------------------------------------------------------------------------
333 
instance()334 GlFontManager *GlFontManager::instance() {
335   if (!m_instance) m_instance = new GlFontManager();
336 
337   return m_instance;
338 }
339 
340 //----------------------------------------------------------------------------
341 
setFont(void * font)342 bool GlFontManager::setFont(void *font) {
343   // cerca il font scelto nella mappa dei fonts conosciuti
344   std::map<void *, double>::iterator it = m_fonts.find(font);
345 
346   // se e' stato trovato
347   if (it != m_fonts.end()) {
348     m_currentFont = font;
349 
350     glPushAttrib(GL_ALL_ATTRIB_BITS);
351     glPushMatrix();
352     m_base = glGenLists(256);
353     glListBase(m_base);
354     int i = 0;
355     for (; i < 256; ++i) {
356       glNewList(m_base + i, GL_COMPILE);
357       glutStrokeCharacter(GLUT_STROKE_ROMAN, i);
358       // glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, i);
359       glEndList();
360     }
361     glPopAttrib();
362     glPopMatrix();
363     return true;
364   }
365   return false;
366 }
367 
368 //----------------------------------------------------------------------------
369 
drawText(std::wstring wtext)370 void GlFontManager::drawText(/*const TRectD bBox,*/
371                              std::wstring wtext /*,
372                              TDimensionD scale*/) {
373   if (!m_currentFont) return;
374 
375   std::string text       = ::to_string(wtext);
376   const char *textString = text.c_str();
377   glListBase(m_base);
378   /*
379 glPushMatrix();
380 glTranslated(bBox.x0, bBox.y0, 0.0);
381 glScaled(scale.lx*0.07, scale.ly*0.07, 1.0);
382 */
383   glCallLists((GLuint)strlen(textString), GL_BYTE, textString);
384   /*glPopMatrix();*/
385 }
386 
387 //============================================================================
388 
389 }  // anonymous namespace
390 
391 //============================================================================
392 
tglDraw(const TCubic & cubic,int precision,GLenum pointOrLine)393 void tglDraw(const TCubic &cubic, int precision, GLenum pointOrLine) {
394   CHECK_ERRORS_BY_GL;
395   assert(pointOrLine == GL_POINT || pointOrLine == GL_LINE);
396   float ctrlPts[4][3];
397 
398   ctrlPts[0][0] = cubic.getP0().x;
399   ctrlPts[0][1] = cubic.getP0().y;
400   ctrlPts[0][2] = 0.0;
401 
402   ctrlPts[1][0] = cubic.getP1().x;
403   ctrlPts[1][1] = cubic.getP1().y;
404   ctrlPts[1][2] = 0.0;
405 
406   ctrlPts[2][0] = cubic.getP2().x;
407   ctrlPts[2][1] = cubic.getP2().y;
408   ctrlPts[2][2] = 0.0;
409 
410   ctrlPts[3][0] = cubic.getP3().x;
411   ctrlPts[3][1] = cubic.getP3().y;
412   ctrlPts[3][2] = 0.0;
413 
414   CHECK_ERRORS_BY_GL;
415   glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &ctrlPts[0][0]);
416   CHECK_ERRORS_BY_GL;
417   glEnable(GL_MAP1_VERTEX_3);
418   CHECK_ERRORS_BY_GL;
419   glMapGrid1f(precision, 0.0, 1.0);
420   CHECK_ERRORS_BY_GL;
421   glEvalMesh1(pointOrLine, 0, precision);
422   CHECK_ERRORS_BY_GL;
423 }
424 
425 //-----------------------------------------------------------------------------
426 
tglDraw(const TRectD & rect,const std::vector<TRaster32P> & textures,bool blending)427 void tglDraw(const TRectD &rect, const std::vector<TRaster32P> &textures,
428              bool blending) {
429   double pixelSize2 = tglGetPixelSize2();
430   // level e' la minore potenza di 2 maggiore di sqrt(pixelSize2)
431   unsigned int level = 1;
432   while (pixelSize2 * level * level <= 1.0) level <<= 1;
433 
434   unsigned int texturesCount = (int)textures.size();
435   if (level > texturesCount) level = texturesCount;
436 
437   level = texturesCount - level;
438 
439   tglDraw(rect, textures[level], blending);
440 }
441 
442 //-------------------------------------------------------------------
443 
tglDraw(const TRectD & rect,const TRaster32P & tex,bool blending)444 void tglDraw(const TRectD &rect, const TRaster32P &tex, bool blending) {
445   CHECK_ERRORS_BY_GL;
446   glPushAttrib(GL_ALL_ATTRIB_BITS);
447   if (blending) {
448     glEnable(GL_BLEND);
449     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
450   }
451 
452   unsigned int texWidth  = 1;
453   unsigned int texHeight = 1;
454 
455   while (texWidth < (unsigned int)tex->getLx()) texWidth = texWidth << 1;
456 
457   while (texHeight < (unsigned int)tex->getLy()) texHeight = texHeight << 1;
458 
459   double lwTex = 1.0;
460   double lhTex = 1.0;
461 
462   TRaster32P texture;
463   unsigned int texLx = (unsigned int)tex->getLx();
464   unsigned int texLy = (unsigned int)tex->getLy();
465 
466   if (texWidth != texLx || texHeight != texLy) {
467     texture = TRaster32P(texWidth, texHeight);
468     texture->fill(TPixel32(0, 0, 0, 0));
469     texture->copy(tex);
470     lwTex = (texLx) / (double)(texWidth);
471     lhTex = (texLy) / (double)(texHeight);
472     if (lwTex > 1.0) lwTex = 1.0;
473     if (lhTex > 1.0) lhTex = 1.0;
474   } else
475     texture = tex;
476   GLenum fmt =
477 #if defined(TNZ_MACHINE_CHANNEL_ORDER_BGRM)
478       GL_BGRA_EXT;
479 #elif defined(TNZ_MACHINE_CHANNEL_ORDER_MBGR)
480       GL_ABGR_EXT;
481 #elif defined(TNZ_MACHINE_CHANNEL_ORDER_RGBM)
482       GL_RGBA;
483 #elif defined(TNZ_MACHINE_CHANNEL_ORDER_MRGB)
484       GL_BGRA;
485 #else
486 //   Error  PLATFORM NOT SUPPORTED
487 #error "unknown channel order!"
488 #endif
489 
490   // Generate a texture id and bind it.
491   GLuint texId;
492   glGenTextures(1, &texId);
493 
494   glBindTexture(GL_TEXTURE_2D, texId);
495 
496   glPixelStorei(GL_UNPACK_ROW_LENGTH, texture->getWrap());
497 
498   texture->lock();
499   glTexImage2D(GL_TEXTURE_2D, 0, 4, texWidth, texHeight, 0, fmt,
500 #ifdef TNZ_MACHINE_CHANNEL_ORDER_MRGB
501                GL_UNSIGNED_INT_8_8_8_8_REV,
502 #else
503                GL_UNSIGNED_BYTE,
504 #endif
505                texture->getRawData());
506 
507   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
508   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
509 
510   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
511   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
512 
513   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
514   glEnable(GL_TEXTURE_2D);
515 
516   glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
517 
518   double rectLx = rect.getLx();
519   double rectLy = rect.getLy();
520 
521   tglColor(TPixel32(0, 0, 0, 0));
522 
523   glPushMatrix();
524 
525   glTranslated(rect.x0, rect.y0, 0.0);
526   glBegin(GL_POLYGON);
527 
528   glTexCoord2d(0, 0);
529   tglVertex(TPointD(0.0, 0.0));
530 
531   glTexCoord2d(lwTex, 0);
532   tglVertex(TPointD(rectLx, 0.0));
533 
534   glTexCoord2d(lwTex, lhTex);
535   tglVertex(TPointD(rectLx, rectLy));
536 
537   glTexCoord2d(0, lhTex);
538   tglVertex(TPointD(0.0, rectLy));
539 
540   glEnd();
541   glDisable(GL_TEXTURE_2D);
542 
543   glPopMatrix();
544   glPopAttrib();
545 
546   // Delete texture
547   glDeleteTextures(1, &texId);
548 
549   texture->unlock();
550 }
551 
552 //-----------------------------------------------------------------------------
553 
tglBuildMipmaps(std::vector<TRaster32P> & rasters,const TFilePath & filepath)554 void tglBuildMipmaps(std::vector<TRaster32P> &rasters,
555                      const TFilePath &filepath) {
556   assert(rasters.size() > 0);
557   TRop::ResampleFilterType resampleFilter = TRop::ClosestPixel;
558   TRasterP ras;
559   TImageReader::load(filepath, ras);
560   int rasLx = ras->getLx();
561   int rasLy = ras->getLy();
562 
563   int lx = 1;
564   while (lx < rasLx) lx <<= 1;
565 
566   int ly = 1;
567   while (ly < rasLy) ly <<= 1;
568 
569   TRaster32P ras2(lx, ly);
570   double sx = (double)lx / (double)ras->getLx();
571   double sy = (double)ly / (double)ras->getLy();
572 #ifndef SCALE_BY_GLU
573   TRop::resample(ras2, ras, TScale(sx, sy), resampleFilter);
574 #else
575   ras->lock();
576   gluScaleImage(GL_RGBA, ras->getLx(), ras->getLy(), GL_UNSIGNED_BYTE,
577                 ras->getRawData(), lx, ly, GL_UNSIGNED_BYTE,
578                 ras2->getRawData());
579   ras->unlock();
580 #endif
581 
582   rasters[0] = ras2;
583   int ras2Lx = ras2->getLx();
584   int ras2Ly = ras2->getLy();
585   for (int i = 1; i < (int)rasters.size(); ++i) {
586     lx >>= 1;
587     ly >>= 1;
588     if (lx < 1) lx = 1;
589     if (ly < 1) ly = 1;
590     rasters[i] = TRaster32P(lx, ly);
591     sx         = (double)lx / (double)ras2Lx;
592     sy         = (double)ly / (double)ras2Ly;
593     rasters[i] = TRaster32P(lx, ly);
594 #ifndef SCALE_BY_GLU
595     TRop::resample(rasters[i], ras2, TScale(sx, sy), resampleFilter);
596 #else
597     ras2->lock();
598     gluScaleImage(GL_RGBA, ras->getLx(), ras->getLy(), GL_UNSIGNED_BYTE,
599                   ras2->getRawData(), lx, ly, GL_UNSIGNED_BYTE,
600                   rasters[i]->getRawData());
601     ras2->unlock();
602 #endif
603   }
604 }
605 
606 //-----------------------------------------------------------------------------
607 // Forse si potrebbe togliere l'ifdef ed usare QT
608 #if defined(_WIN32)
609 
tglGetCurrentContext()610 TGlContext tglGetCurrentContext() {
611   return std::make_pair(wglGetCurrentDC(), wglGetCurrentContext());
612 }
613 
tglMakeCurrent(TGlContext context)614 void tglMakeCurrent(TGlContext context) {
615   wglMakeCurrent(context.first, context.second);
616 }
617 
tglDoneCurrent(TGlContext)618 void tglDoneCurrent(TGlContext) { wglMakeCurrent(NULL, NULL); }
619 
620 #elif defined(LINUX) || defined(FREEBSD) || defined(__sgi) || defined(MACOSX)
621 
tglGetCurrentContext()622 TGlContext tglGetCurrentContext() {
623   return reinterpret_cast<TGlContext>(
624       const_cast<QGLContext *>(QGLContext::currentContext()));
625 
626   // (Daniele) I'm not sure why QGLContext::currentContext() returns
627   // const. I think it shouldn't, and guess (hope) this is safe...
628 }
629 
tglMakeCurrent(TGlContext context)630 void tglMakeCurrent(TGlContext context) {
631   if (context)
632     reinterpret_cast<QGLContext *>(context)->makeCurrent();
633   else
634     tglDoneCurrent(tglGetCurrentContext());
635 }
636 
tglDoneCurrent(TGlContext context)637 void tglDoneCurrent(TGlContext context) {
638   if (context) reinterpret_cast<QGLContext *>(context)->doneCurrent();
639 }
640 
641 #else
642 #error "unknown platform!"
643 #endif
644 
645 //-----------------------------------------------------------------------------
646 //  End Of File
647 //-----------------------------------------------------------------------------
648