b377c5e789ca4224106d190b866f18c324d936f7
[occt.git] / src / OpenGl / OpenGl_Context.cxx
1 // Created on: 2012-01-26
2 // Created by: Kirill GAVRILOV
3 // Copyright (c) 2012-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 under
8 // the terms of the GNU Lesser General Public License 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 #if defined(_WIN32)
17   #include <windows.h>
18 #endif
19
20 #include <OpenGl_Context.hxx>
21
22 #include <OpenGl_ArbTBO.hxx>
23 #include <OpenGl_ArbIns.hxx>
24 #include <OpenGl_ArbDbg.hxx>
25 #include <OpenGl_ArbFBO.hxx>
26 #include <OpenGl_ExtGS.hxx>
27 #include <OpenGl_ArbTexBindless.hxx>
28 #include <OpenGl_GlCore44.hxx>
29 #include <OpenGl_FrameBuffer.hxx>
30 #include <OpenGl_Sampler.hxx>
31 #include <OpenGl_ShaderManager.hxx>
32 #include <OpenGl_Workspace.hxx>
33 #include <OpenGl_AspectFace.hxx>
34 #include <Graphic3d_TransformUtils.hxx>
35
36 #include <Message_Messenger.hxx>
37
38 #include <NCollection_Vector.hxx>
39
40 #include <Standard_ProgramError.hxx>
41
42 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Context,Standard_Transient)
43
44 #if defined(HAVE_EGL)
45   #include <EGL/egl.h>
46   #ifdef _MSC_VER
47     #pragma comment(lib, "libEGL.lib")
48   #endif
49 #elif defined(_WIN32)
50   //
51 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
52   #include <dlfcn.h>
53   #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
54     //
55   #else
56     #include <OpenGL/OpenGL.h>
57     #include <CoreGraphics/CoreGraphics.h>
58   #endif
59 #else
60   #include <GL/glx.h> // glXGetProcAddress()
61 #endif
62
63 #ifdef HAVE_GL2PS
64   #include <gl2ps.h>
65   #ifdef _MSC_VER
66     #pragma comment (lib, "gl2ps.lib")
67   #endif
68 #endif
69
70
71 namespace
72 {
73   static const Handle(OpenGl_Resource) NULL_GL_RESOURCE;
74   static const OpenGl_Mat4 THE_IDENTITY_MATRIX;
75
76   //! Add key-value pair to the dictionary.
77   static void addInfo (TColStd_IndexedDataMapOfStringString& theDict,
78                        const TCollection_AsciiString& theKey,
79                        const TCollection_AsciiString& theValue)
80   {
81     theDict.ChangeFromIndex (theDict.Add (theKey, theValue)) = theValue;
82   }
83
84   //! Add key-value pair to the dictionary.
85   static void addInfo (TColStd_IndexedDataMapOfStringString& theDict,
86                        const TCollection_AsciiString& theKey,
87                        const char* theValue)
88   {
89     TCollection_AsciiString aValue (theValue != NULL ? theValue : "");
90     theDict.ChangeFromIndex (theDict.Add (theKey, aValue)) = aValue;
91   }
92 }
93
94 // =======================================================================
95 // function : OpenGl_Context
96 // purpose  :
97 // =======================================================================
98 OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps)
99 : core11     (NULL),
100   core11fwd  (NULL),
101   core15     (NULL),
102   core15fwd  (NULL),
103   core20     (NULL),
104   core20fwd  (NULL),
105   core32     (NULL),
106   core32back (NULL),
107   core33     (NULL),
108   core33back (NULL),
109   core41     (NULL),
110   core41back (NULL),
111   core42     (NULL),
112   core42back (NULL),
113   core43     (NULL),
114   core43back (NULL),
115   core44     (NULL),
116   core44back (NULL),
117   caps   (!theCaps.IsNull() ? theCaps : new OpenGl_Caps()),
118 #if defined(GL_ES_VERSION_2_0)
119   hasHighp   (Standard_False),
120   hasUintIndex(Standard_False),
121   hasTexRGBA8(Standard_False),
122 #else
123   hasHighp   (Standard_True),
124   hasUintIndex(Standard_True),
125   hasTexRGBA8(Standard_True),
126 #endif
127   arbNPTW  (Standard_False),
128   arbTexRG (Standard_False),
129   arbTexFloat (Standard_False),
130   arbTexBindless (NULL),
131   arbTBO (NULL),
132   arbTboRGB32 (Standard_False),
133   arbIns (NULL),
134   arbDbg (NULL),
135   arbFBO (NULL),
136   arbFBOBlit (NULL),
137   extFragDepth (Standard_False),
138   extGS  (NULL),
139   extBgra(Standard_False),
140   extAnis(Standard_False),
141   extPDS (Standard_False),
142   atiMem (Standard_False),
143   nvxMem (Standard_False),
144   mySharedResources (new OpenGl_ResourcesMap()),
145   myDelayed         (new OpenGl_DelayReleaseMap()),
146   myUnusedResources (new OpenGl_ResourcesStack()),
147   myClippingState (),
148   myGlLibHandle (NULL),
149   myFuncs (new OpenGl_GlFunctions()),
150   myAnisoMax   (1),
151   myTexClamp   (GL_CLAMP_TO_EDGE),
152   myMaxTexDim  (1024),
153   myMaxClipPlanes (6),
154   myMaxMsaaSamples(0),
155   myGlVerMajor (0),
156   myGlVerMinor (0),
157   myIsInitialized (Standard_False),
158   myIsStereoBuffers (Standard_False),
159   myIsGlNormalizeEnabled (Standard_False),
160   myHasRayTracing (Standard_False),
161   myHasRayTracingTextures (Standard_False),
162   myHasRayTracingAdaptiveSampling (Standard_False),
163 #if !defined(GL_ES_VERSION_2_0)
164   myPointSpriteOrig (GL_UPPER_LEFT),
165   myRenderMode (GL_RENDER),
166   myPolygonMode (GL_FILL),
167 #else
168   myPointSpriteOrig (0),
169   myRenderMode (0),
170   myPolygonMode (0),
171 #endif
172   myToCullBackFaces (false),
173   myReadBuffer (0),
174   myDrawBuffer (0),
175   myDefaultVao (0),
176   myIsGlDebugCtx (Standard_False),
177   myResolutionRatio (1.0f)
178 {
179   myViewport[0] = 0;
180   myViewport[1] = 0;
181   myViewport[2] = 0;
182   myViewport[3] = 0;
183
184   // system-dependent fields
185 #if defined(HAVE_EGL)
186   myDisplay  = (Aspect_Display          )EGL_NO_DISPLAY;
187   myWindow   = (Aspect_Drawable         )EGL_NO_SURFACE;
188   myGContext = (Aspect_RenderingContext )EGL_NO_CONTEXT;
189 #elif defined(_WIN32)
190   myWindow   = NULL;
191   myWindowDC = NULL;
192   myGContext = NULL;
193 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
194   // Vendors can not extend functionality on this system
195   // and developers are limited to OpenGL support provided by Mac OS X SDK.
196   // We retrieve function pointers from system library
197   // to generalize extensions support on all platforms.
198   // In this way we also reach binary compatibility benefit between OS releases
199   // if some newest functionality is optionally used.
200   // Notice that GL version / extension availability checks are required
201   // because function pointers may be available but not functionality itself
202   // (depends on renderer).
203 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
204   myGContext    = NULL;
205   myGlLibHandle = dlopen ("/System/Library/Frameworks/OpenGLES.framework/OpenGLES", RTLD_LAZY);
206 #else
207   myGContext    = NULL;
208   myGlLibHandle = dlopen ("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
209 #endif
210 #else
211   myDisplay =  NULL;
212   myWindow   = 0;
213   myGContext = 0;
214 #endif
215
216   memset (myFuncs.operator->(), 0, sizeof(OpenGl_GlFunctions));
217   myShaderManager = new OpenGl_ShaderManager (this);
218 }
219
220 // =======================================================================
221 // function : ~OpenGl_Context
222 // purpose  :
223 // =======================================================================
224 OpenGl_Context::~OpenGl_Context()
225 {
226   // release clean up queue
227   ReleaseDelayed();
228
229 #if !defined(GL_ES_VERSION_2_0)
230   // release default VAO
231   if (myDefaultVao != 0
232    && IsValid()
233    && core32 != NULL)
234   {
235     core32->glDeleteVertexArrays (1, &myDefaultVao);
236   }
237   myDefaultVao = 0;
238 #endif
239
240   // release default FBO
241   if (!myDefaultFbo.IsNull())
242   {
243     myDefaultFbo->Release (this);
244     myDefaultFbo.Nullify();
245   }
246
247   // release shared resources if any
248   if (mySharedResources->GetRefCount() <= 1)
249   {
250     myShaderManager.Nullify();
251     for (NCollection_DataMap<TCollection_AsciiString, Handle(OpenGl_Resource)>::Iterator anIter (*mySharedResources);
252          anIter.More(); anIter.Next())
253     {
254       anIter.Value()->Release (this);
255     }
256
257     // release delayed resources added during deletion of shared resources
258     while (!myUnusedResources->IsEmpty())
259     {
260       myUnusedResources->First()->Release (this);
261       myUnusedResources->RemoveFirst();
262     }
263   }
264   else if (myShaderManager->IsSameContext (this))
265   {
266     myShaderManager->SetContext (NULL);
267   }
268   mySharedResources.Nullify();
269   myDelayed.Nullify();
270
271   // release sampler object
272   if (!myTexSampler.IsNull())
273   {
274     myTexSampler->Release (this);
275   }
276
277   if (arbDbg != NULL
278    && myIsGlDebugCtx
279    && IsValid())
280   {
281     // reset callback
282   #if !defined(GL_ES_VERSION_2_0)
283     void* aPtr = NULL;
284     glGetPointerv (GL_DEBUG_CALLBACK_USER_PARAM, &aPtr);
285     if (aPtr == this)
286   #endif
287     {
288       arbDbg->glDebugMessageCallback (NULL, NULL);
289     }
290     myIsGlDebugCtx = Standard_False;
291   }
292 }
293
294 // =======================================================================
295 // function : forcedRelease
296 // purpose  :
297 // =======================================================================
298 void OpenGl_Context::forcedRelease()
299 {
300   ReleaseDelayed();
301   for (NCollection_DataMap<TCollection_AsciiString, Handle(OpenGl_Resource)>::Iterator anIter (*mySharedResources);
302        anIter.More(); anIter.Next())
303   {
304     anIter.Value()->Release (this);
305   }
306   mySharedResources->Clear();
307   myShaderManager->clear();
308   myShaderManager->SetContext (NULL);
309
310   // release delayed resources added during deletion of shared resources
311   while (!myUnusedResources->IsEmpty())
312   {
313     myUnusedResources->First()->Release (this);
314     myUnusedResources->RemoveFirst();
315   }
316 }
317
318 // =======================================================================
319 // function : ResizeViewport
320 // purpose  :
321 // =======================================================================
322 void OpenGl_Context::ResizeViewport (const Standard_Integer* theRect)
323 {
324   core11fwd->glViewport (theRect[0], theRect[1], theRect[2], theRect[3]);
325   myViewport[0] = theRect[0];
326   myViewport[1] = theRect[1];
327   myViewport[2] = theRect[2];
328   myViewport[3] = theRect[3];
329 }
330
331 #if !defined(GL_ES_VERSION_2_0)
332 inline Standard_Integer stereoToMonoBuffer (const Standard_Integer theBuffer)
333 {
334   switch (theBuffer)
335   {
336     case GL_BACK_LEFT:
337     case GL_BACK_RIGHT:
338       return GL_BACK;
339     case GL_FRONT_LEFT:
340     case GL_FRONT_RIGHT:
341       return GL_FRONT;
342     default:
343       return theBuffer;
344   }
345 }
346 #endif
347
348 // =======================================================================
349 // function : SetReadBuffer
350 // purpose  :
351 // =======================================================================
352 void OpenGl_Context::SetReadBuffer (const Standard_Integer theReadBuffer)
353 {
354 #if !defined(GL_ES_VERSION_2_0)
355   myReadBuffer = !myIsStereoBuffers ? stereoToMonoBuffer (theReadBuffer) : theReadBuffer;
356   if (myReadBuffer < GL_COLOR_ATTACHMENT0
357    && arbFBO != NULL)
358   {
359     arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
360   }
361   ::glReadBuffer (myReadBuffer);
362 #else
363   (void )theReadBuffer;
364 #endif
365 }
366
367 // =======================================================================
368 // function : SetDrawBuffer
369 // purpose  :
370 // =======================================================================
371 void OpenGl_Context::SetDrawBuffer (const Standard_Integer theDrawBuffer)
372 {
373 #if !defined(GL_ES_VERSION_2_0)
374   myDrawBuffer = !myIsStereoBuffers ? stereoToMonoBuffer (theDrawBuffer) : theDrawBuffer;
375   if (myDrawBuffer < GL_COLOR_ATTACHMENT0
376    && arbFBO != NULL)
377   {
378     arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
379   }
380   ::glDrawBuffer (myDrawBuffer);
381 #else
382   (void )theDrawBuffer;
383 #endif
384 }
385
386 // =======================================================================
387 // function : SetCullBackFaces
388 // purpose  :
389 // =======================================================================
390 void OpenGl_Context::SetCullBackFaces (bool theToEnable)
391 {
392   if (myToCullBackFaces == theToEnable)
393   {
394     return;
395   }
396
397   myToCullBackFaces = theToEnable;
398   if (theToEnable)
399   {
400     //glCullFace (GL_BACK); GL_BACK by default
401     core11fwd->glEnable (GL_CULL_FACE);
402   }
403   else
404   {
405     core11fwd->glDisable (GL_CULL_FACE);
406   }
407 }
408
409 // =======================================================================
410 // function : FetchState
411 // purpose  :
412 // =======================================================================
413 void OpenGl_Context::FetchState()
414 {
415 #if !defined(GL_ES_VERSION_2_0)
416   // cache feedback mode state
417   if (core11 != NULL)
418   {
419     ::glGetIntegerv (GL_RENDER_MODE, &myRenderMode);
420   }
421
422   // cache buffers state
423   ::glGetIntegerv (GL_READ_BUFFER, &myReadBuffer);
424   ::glGetIntegerv (GL_DRAW_BUFFER, &myDrawBuffer);
425 #endif
426 }
427
428 // =======================================================================
429 // function : Share
430 // purpose  :
431 // =======================================================================
432 void OpenGl_Context::Share (const Handle(OpenGl_Context)& theShareCtx)
433 {
434   if (!theShareCtx.IsNull())
435   {
436     mySharedResources = theShareCtx->mySharedResources;
437     myDelayed         = theShareCtx->myDelayed;
438     myUnusedResources = theShareCtx->myUnusedResources;
439     myShaderManager   = theShareCtx->myShaderManager;
440   }
441 }
442
443 #if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
444
445 // =======================================================================
446 // function : IsCurrent
447 // purpose  :
448 // =======================================================================
449 Standard_Boolean OpenGl_Context::IsCurrent() const
450 {
451 #if defined(HAVE_EGL)
452   if ((EGLDisplay )myDisplay  == EGL_NO_DISPLAY
453    || (EGLSurface )myWindow   == EGL_NO_SURFACE
454    || (EGLContext )myGContext == EGL_NO_CONTEXT)
455   {
456     return Standard_False;
457   }
458
459   return (((EGLDisplay )myDisplay  == eglGetCurrentDisplay())
460        && ((EGLContext )myGContext == eglGetCurrentContext())
461        && ((EGLSurface )myWindow   == eglGetCurrentSurface (EGL_DRAW)));
462 #elif defined(_WIN32)
463   if (myWindowDC == NULL || myGContext == NULL)
464   {
465     return Standard_False;
466   }
467   return (( (HDC )myWindowDC == wglGetCurrentDC())
468       && ((HGLRC )myGContext == wglGetCurrentContext()));
469 #else
470   if (myDisplay == NULL || myWindow == 0 || myGContext == 0)
471   {
472     return Standard_False;
473   }
474
475   return (   ((Display* )myDisplay  == glXGetCurrentDisplay())
476        &&  ((GLXContext )myGContext == glXGetCurrentContext())
477        && ((GLXDrawable )myWindow   == glXGetCurrentDrawable()));
478 #endif
479 }
480
481 // =======================================================================
482 // function : MakeCurrent
483 // purpose  :
484 // =======================================================================
485 Standard_Boolean OpenGl_Context::MakeCurrent()
486 {
487 #if defined(HAVE_EGL)
488   if ((EGLDisplay )myDisplay  == EGL_NO_DISPLAY
489    || (EGLSurface )myWindow   == EGL_NO_SURFACE
490    || (EGLContext )myGContext == EGL_NO_CONTEXT)
491   {
492     Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
493     return Standard_False;
494   }
495
496   if (eglMakeCurrent ((EGLDisplay )myDisplay, (EGLSurface )myWindow, (EGLSurface )myWindow, (EGLContext )myGContext) != EGL_TRUE)
497   {
498     // if there is no current context it might be impossible to use glGetError() correctly
499     PushMessage (GL_DEBUG_SOURCE_WINDOW_SYSTEM, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
500                  "eglMakeCurrent() has failed!");
501     myIsInitialized = Standard_False;
502     return Standard_False;
503   }
504 #elif defined(_WIN32)
505   if (myWindowDC == NULL || myGContext == NULL)
506   {
507     Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
508     return Standard_False;
509   }
510
511   // technically it should be safe to activate already bound GL context
512   // however some drivers (Intel etc.) may FAIL doing this for unknown reason
513   if (IsCurrent())
514   {
515     myShaderManager->SetContext (this);
516     return Standard_True;
517   }
518   else if (wglMakeCurrent ((HDC )myWindowDC, (HGLRC )myGContext) != TRUE)
519   {
520     // notice that glGetError() couldn't be used here!
521     wchar_t* aMsgBuff = NULL;
522     DWORD anErrorCode = GetLastError();
523     FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
524                     NULL, anErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (wchar_t* )&aMsgBuff, 0, NULL);
525     TCollection_ExtendedString aMsg ("wglMakeCurrent() has failed. ");
526     if (aMsgBuff != NULL)
527     {
528       aMsg += (Standard_ExtString )aMsgBuff;
529       LocalFree (aMsgBuff);
530     }
531     PushMessage (GL_DEBUG_SOURCE_WINDOW_SYSTEM, GL_DEBUG_TYPE_ERROR, (unsigned int )anErrorCode, GL_DEBUG_SEVERITY_HIGH, aMsg);
532     myIsInitialized = Standard_False;
533     return Standard_False;
534   }
535 #else
536   if (myDisplay == NULL || myWindow == 0 || myGContext == 0)
537   {
538     Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
539     return Standard_False;
540   }
541
542   if (!glXMakeCurrent ((Display* )myDisplay, (GLXDrawable )myWindow, (GLXContext )myGContext))
543   {
544     // if there is no current context it might be impossible to use glGetError() correctly
545     PushMessage (GL_DEBUG_SOURCE_WINDOW_SYSTEM, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
546                  "glXMakeCurrent() has failed!");
547     myIsInitialized = Standard_False;
548     return Standard_False;
549   }
550 #endif
551   myShaderManager->SetContext (this);
552   return Standard_True;
553 }
554
555 // =======================================================================
556 // function : SwapBuffers
557 // purpose  :
558 // =======================================================================
559 void OpenGl_Context::SwapBuffers()
560 {
561 #if defined(HAVE_EGL)
562   if ((EGLSurface )myWindow != EGL_NO_SURFACE)
563   {
564     eglSwapBuffers ((EGLDisplay )myDisplay, (EGLSurface )myWindow);
565   }
566 #elif defined(_WIN32)
567   if ((HDC )myWindowDC != NULL)
568   {
569     ::SwapBuffers ((HDC )myWindowDC);
570     glFlush();
571   }
572 #else
573   if ((Display* )myDisplay != NULL)
574   {
575     glXSwapBuffers ((Display* )myDisplay, (GLXDrawable )myWindow);
576   }
577 #endif
578 }
579
580 #endif // __APPLE__
581
582 // =======================================================================
583 // function : SetSwapInterval
584 // purpose  :
585 // =======================================================================
586 Standard_Boolean OpenGl_Context::SetSwapInterval (const Standard_Integer theInterval)
587 {
588 #if defined(HAVE_EGL)
589   if (::eglSwapInterval ((EGLDisplay )myDisplay, theInterval) == EGL_TRUE)
590   {
591     return Standard_True;
592   }
593 #elif defined(_WIN32)
594   if (myFuncs->wglSwapIntervalEXT != NULL)
595   {
596     myFuncs->wglSwapIntervalEXT (theInterval);
597     return Standard_True;
598   }
599 #elif defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
600   //
601 #elif defined(__APPLE__)
602   if (::CGLSetParameter (CGLGetCurrentContext(), kCGLCPSwapInterval, &theInterval) == kCGLNoError)
603   {
604     return Standard_True;
605   }
606 #else
607   if (theInterval == -1
608    && myFuncs->glXSwapIntervalEXT != NULL)
609   {
610     typedef int (*glXSwapIntervalEXT_t_x)(Display* theDisplay, GLXDrawable theDrawable, int theInterval);
611     glXSwapIntervalEXT_t_x aFuncPtr = (glXSwapIntervalEXT_t_x )myFuncs->glXSwapIntervalEXT;
612     aFuncPtr ((Display* )myDisplay, (GLXDrawable )myWindow, theInterval);
613     return Standard_True;
614   }
615   else if (myFuncs->glXSwapIntervalSGI != NULL)
616   {
617     myFuncs->glXSwapIntervalSGI (theInterval);
618     return Standard_True;
619   }
620 #endif
621   return Standard_False;
622 }
623
624 // =======================================================================
625 // function : findProc
626 // purpose  :
627 // =======================================================================
628 void* OpenGl_Context::findProc (const char* theFuncName)
629 {
630 #if defined(HAVE_EGL)
631   return (void* )eglGetProcAddress (theFuncName);
632 #elif defined(_WIN32)
633   return (void* )wglGetProcAddress (theFuncName);
634 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
635   return (myGlLibHandle != NULL) ? dlsym (myGlLibHandle, theFuncName) : NULL;
636 #else
637   return (void* )glXGetProcAddress ((const GLubyte* )theFuncName);
638 #endif
639 }
640
641 // =======================================================================
642 // function : CheckExtension
643 // purpose  :
644 // =======================================================================
645 Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtName) const
646 {
647   if (theExtName  == NULL)
648   {
649 #ifdef OCCT_DEBUG
650     std::cerr << "CheckExtension called with NULL string!\n";
651 #endif
652     return Standard_False;
653   }
654
655 #if !defined(GL_ES_VERSION_2_0)
656   // available since OpenGL 3.0
657   // and the ONLY way to check extensions with OpenGL 3.1+ core profile
658   if (IsGlGreaterEqual (3, 0)
659    && myFuncs->glGetStringi != NULL)
660   {
661     GLint anExtNb = 0;
662     ::glGetIntegerv (GL_NUM_EXTENSIONS, &anExtNb);
663     const size_t anExtNameLen = strlen (theExtName);
664     for (GLint anIter = 0; anIter < anExtNb; ++anIter)
665     {
666       const char* anExtension = (const char* )myFuncs->glGetStringi (GL_EXTENSIONS, (GLuint )anIter);
667       const size_t aTestExtNameLen = strlen (anExtension);
668       if (aTestExtNameLen == anExtNameLen
669        && strncmp (anExtension, theExtName, anExtNameLen) == 0)
670       {
671         return Standard_True;
672       }
673     }
674     return Standard_False;
675   }
676 #endif
677
678   // use old way with huge string for all extensions
679   const char* anExtString = (const char* )glGetString (GL_EXTENSIONS);
680   if (anExtString == NULL)
681   {
682     Messenger()->Send ("TKOpenGL: glGetString (GL_EXTENSIONS) has returned NULL! No GL context?", Message_Warning);
683     return Standard_False;
684   }
685   return CheckExtension (anExtString, theExtName);
686 }
687
688 // =======================================================================
689 // function : CheckExtension
690 // purpose  :
691 // =======================================================================
692 Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtString,
693                                                  const char* theExtName)
694 {
695   if (theExtString == NULL)
696   {
697     return Standard_False;
698   }
699
700   // Search for theExtName in the extensions string.
701   // Use of strstr() is not sufficient because extension names can be prefixes of other extension names.
702   char* aPtrIter = (char* )theExtString;
703   const char*  aPtrEnd      = aPtrIter + strlen (theExtString);
704   const size_t anExtNameLen = strlen (theExtName);
705   while (aPtrIter < aPtrEnd)
706   {
707     const size_t n = strcspn (aPtrIter, " ");
708     if ((n == anExtNameLen) && (strncmp (aPtrIter, theExtName, anExtNameLen) == 0))
709     {
710       return Standard_True;
711     }
712     aPtrIter += (n + 1);
713   }
714   return Standard_False;
715 }
716
717 #if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
718
719 // =======================================================================
720 // function : Init
721 // purpose  :
722 // =======================================================================
723 Standard_Boolean OpenGl_Context::Init (const Standard_Boolean theIsCoreProfile)
724 {
725   if (myIsInitialized)
726   {
727     return Standard_True;
728   }
729
730 #if defined(HAVE_EGL)
731   myDisplay  = (Aspect_Display )eglGetCurrentDisplay();
732   myGContext = (Aspect_RenderingContext )eglGetCurrentContext();
733   myWindow   = (Aspect_Drawable )eglGetCurrentSurface(EGL_DRAW);
734 #elif defined(_WIN32)
735   myWindowDC = (Aspect_Handle )wglGetCurrentDC();
736   myGContext = (Aspect_RenderingContext )wglGetCurrentContext();
737 #else
738   myDisplay  = (Aspect_Display )glXGetCurrentDisplay();
739   myGContext = (Aspect_RenderingContext )glXGetCurrentContext();
740   myWindow   = (Aspect_Drawable )glXGetCurrentDrawable();
741 #endif
742   if (myGContext == NULL)
743   {
744     return Standard_False;
745   }
746
747   init (theIsCoreProfile);
748   myIsInitialized = Standard_True;
749   return Standard_True;
750 }
751
752 #endif // __APPLE__
753
754 // =======================================================================
755 // function : Init
756 // purpose  :
757 // =======================================================================
758 #if defined(HAVE_EGL)
759 Standard_Boolean OpenGl_Context::Init (const Aspect_Drawable         theEglSurface,
760                                        const Aspect_Display          theEglDisplay,
761                                        const Aspect_RenderingContext theEglContext,
762                                        const Standard_Boolean        theIsCoreProfile)
763 #elif defined(_WIN32)
764 Standard_Boolean OpenGl_Context::Init (const Aspect_Handle           theWindow,
765                                        const Aspect_Handle           theWindowDC,
766                                        const Aspect_RenderingContext theGContext,
767                                        const Standard_Boolean        theIsCoreProfile)
768 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
769
770 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
771 Standard_Boolean OpenGl_Context::Init (EAGLContext*                  theGContext,
772                                        const Standard_Boolean        theIsCoreProfile)
773 #else
774 Standard_Boolean OpenGl_Context::Init (NSOpenGLContext*              theGContext,
775                                        const Standard_Boolean        theIsCoreProfile)
776 #endif
777
778 #else
779 Standard_Boolean OpenGl_Context::Init (const Aspect_Drawable         theWindow,
780                                        const Aspect_Display          theDisplay,
781                                        const Aspect_RenderingContext theGContext,
782                                        const Standard_Boolean        theIsCoreProfile)
783 #endif
784 {
785   Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called only once!");
786 #if defined(HAVE_EGL)
787   myWindow   = theEglSurface;
788   myGContext = theEglContext;
789   myDisplay  = theEglDisplay;
790 #elif defined(_WIN32)
791   myWindow   = theWindow;
792   myGContext = theGContext;
793   myWindowDC = theWindowDC;
794 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
795   myGContext = theGContext;
796 #else
797   myWindow   = theWindow;
798   myGContext = theGContext;
799   myDisplay  = theDisplay;
800 #endif
801   if (myGContext == NULL || !MakeCurrent())
802   {
803     return Standard_False;
804   }
805
806   init (theIsCoreProfile);
807   myIsInitialized = Standard_True;
808   return Standard_True;
809 }
810
811 // =======================================================================
812 // function : ResetErrors
813 // purpose  :
814 // =======================================================================
815 bool OpenGl_Context::ResetErrors (const bool theToPrintErrors)
816 {
817   int aPrevErr = 0;
818   int anErr    = ::glGetError();
819   const bool hasError = anErr != GL_NO_ERROR;
820   if (!theToPrintErrors)
821   {
822     for (; anErr != GL_NO_ERROR && aPrevErr != anErr; aPrevErr = anErr, anErr = ::glGetError())
823     {
824       //
825     }
826     return hasError;
827   }
828
829   for (; anErr != GL_NO_ERROR && aPrevErr != anErr; aPrevErr = anErr, anErr = ::glGetError())
830   {
831     TCollection_ExtendedString anErrId;
832     switch (anErr)
833     {
834       case GL_INVALID_ENUM:      anErrId = "GL_INVALID_ENUM";      break;
835       case GL_INVALID_VALUE:     anErrId = "GL_INVALID_VALUE";     break;
836       case GL_INVALID_OPERATION: anErrId = "GL_INVALID_OPERATION"; break;
837     #ifdef GL_STACK_OVERFLOW
838       case GL_STACK_OVERFLOW:    anErrId = "GL_STACK_OVERFLOW";    break;
839       case GL_STACK_UNDERFLOW:   anErrId = "GL_STACK_UNDERFLOW";   break;
840     #endif
841       case GL_OUT_OF_MEMORY:     anErrId = "GL_OUT_OF_MEMORY";     break;
842       case GL_INVALID_FRAMEBUFFER_OPERATION:
843         anErrId = "GL_INVALID_FRAMEBUFFER_OPERATION";
844         break;
845       default:
846         anErrId = TCollection_ExtendedString("#") + anErr;
847         break;
848     }
849
850     const TCollection_ExtendedString aMsg = TCollection_ExtendedString ("Unhandled GL error: ") + anErrId;
851     PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_OTHER, 0, GL_DEBUG_SEVERITY_LOW, aMsg);
852   }
853   return hasError;
854 }
855
856 // =======================================================================
857 // function : ReadGlVersion
858 // purpose  :
859 // =======================================================================
860 void OpenGl_Context::ReadGlVersion (Standard_Integer& theGlVerMajor,
861                                     Standard_Integer& theGlVerMinor)
862 {
863   // reset values
864   theGlVerMajor = 0;
865   theGlVerMinor = 0;
866
867 #ifdef GL_MAJOR_VERSION
868   // available since OpenGL 3.0 and OpenGL 3.0 ES
869   GLint aMajor = 0, aMinor = 0;
870   glGetIntegerv (GL_MAJOR_VERSION, &aMajor);
871   glGetIntegerv (GL_MINOR_VERSION, &aMinor);
872   // glGetError() sometimes does not report an error here even if
873   // GL does not know GL_MAJOR_VERSION and GL_MINOR_VERSION constants.
874   // This happens on some renderers like e.g. Cygwin MESA.
875   // Thus checking additionally if GL has put anything to
876   // the output variables.
877   if (::glGetError() == GL_NO_ERROR && aMajor != 0 && aMinor != 0)
878   {
879     theGlVerMajor = aMajor;
880     theGlVerMinor = aMinor;
881     return;
882   }
883   for (GLenum anErr = ::glGetError(), aPrevErr = GL_NO_ERROR;; aPrevErr = anErr, anErr = ::glGetError())
884   {
885     if (anErr == GL_NO_ERROR
886      || anErr == aPrevErr)
887     {
888       break;
889     }
890   }
891 #endif
892
893   // Read version string.
894   // Notice that only first two numbers split by point '2.1 XXXXX' are significant.
895   // Following trash (after space) is vendor-specific.
896   // New drivers also returns micro version of GL like '3.3.0' which has no meaning
897   // and should be considered as vendor-specific too.
898   const char* aVerStr = (const char* )glGetString (GL_VERSION);
899   if (aVerStr == NULL || *aVerStr == '\0')
900   {
901     // invalid GL context
902     return;
903   }
904
905 //#if defined(GL_ES_VERSION_2_0)
906   // skip "OpenGL ES-** " section
907   for (; *aVerStr != '\0'; ++aVerStr)
908   {
909     if (*aVerStr >= '0' && *aVerStr <= '9')
910     {
911       break;
912     }
913   }
914 //#endif
915
916   // parse string for major number
917   char aMajorStr[32];
918   char aMinorStr[32];
919   size_t aMajIter = 0;
920   while (aVerStr[aMajIter] >= '0' && aVerStr[aMajIter] <= '9')
921   {
922     ++aMajIter;
923   }
924   if (aMajIter == 0 || aMajIter >= sizeof(aMajorStr))
925   {
926     return;
927   }
928   memcpy (aMajorStr, aVerStr, aMajIter);
929   aMajorStr[aMajIter] = '\0';
930
931   // parse string for minor number
932   aVerStr += aMajIter + 1;
933   size_t aMinIter = 0;
934   while (aVerStr[aMinIter] >= '0' && aVerStr[aMinIter] <= '9')
935   {
936     ++aMinIter;
937   }
938   if (aMinIter == 0 || aMinIter >= sizeof(aMinorStr))
939   {
940     return;
941   }
942   memcpy (aMinorStr, aVerStr, aMinIter);
943   aMinorStr[aMinIter] = '\0';
944
945   // read numbers
946   theGlVerMajor = atoi (aMajorStr);
947   theGlVerMinor = atoi (aMinorStr);
948
949   if (theGlVerMajor <= 0)
950   {
951     theGlVerMajor = 0;
952     theGlVerMinor = 0;
953   }
954 }
955
956 static Standard_CString THE_DBGMSG_UNKNOWN = "UNKNOWN";
957 static Standard_CString THE_DBGMSG_SOURCES[] =
958 {
959   ".OpenGL",    // GL_DEBUG_SOURCE_API
960   ".WinSystem", // GL_DEBUG_SOURCE_WINDOW_SYSTEM
961   ".GLSL",      // GL_DEBUG_SOURCE_SHADER_COMPILER
962   ".3rdParty",  // GL_DEBUG_SOURCE_THIRD_PARTY
963   "",           // GL_DEBUG_SOURCE_APPLICATION
964   ".Other"      // GL_DEBUG_SOURCE_OTHER
965 };
966
967 static Standard_CString THE_DBGMSG_TYPES[] =
968 {
969   "Error",           // GL_DEBUG_TYPE_ERROR
970   "Deprecated",      // GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR
971   "Undef. behavior", // GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR
972   "Portability",     // GL_DEBUG_TYPE_PORTABILITY
973   "Performance",     // GL_DEBUG_TYPE_PERFORMANCE
974   "Other"            // GL_DEBUG_TYPE_OTHER
975 };
976
977 static Standard_CString THE_DBGMSG_SEV_HIGH   = "High";   // GL_DEBUG_SEVERITY_HIGH
978 static Standard_CString THE_DBGMSG_SEV_MEDIUM = "Medium"; // GL_DEBUG_SEVERITY_MEDIUM
979 static Standard_CString THE_DBGMSG_SEV_LOW    = "Low";    // GL_DEBUG_SEVERITY_LOW
980
981 //! Callback for GL_ARB_debug_output extension
982 static void APIENTRY debugCallbackWrap(unsigned int theSource,
983                                        unsigned int theType,
984                                        unsigned int theId,
985                                        unsigned int theSeverity,
986                                        int          /*theLength*/,
987                                        const char*  theMessage,
988                                        const void*  theUserParam)
989 {
990   OpenGl_Context* aCtx = (OpenGl_Context* )theUserParam;
991   aCtx->PushMessage (theSource, theType, theId, theSeverity, theMessage);
992 }
993
994 // =======================================================================
995 // function : PushMessage
996 // purpose  :
997 // =======================================================================
998 void OpenGl_Context::PushMessage (const unsigned int theSource,
999                                   const unsigned int theType,
1000                                   const unsigned int theId,
1001                                   const unsigned int theSeverity,
1002                                   const TCollection_ExtendedString& theMessage)
1003 {
1004   if (caps->suppressExtraMsg
1005    && theSource >= GL_DEBUG_SOURCE_API
1006    && theSource <= GL_DEBUG_SOURCE_OTHER
1007    && myFilters[theSource - GL_DEBUG_SOURCE_API].Contains (theId))
1008   {
1009     return;
1010   }
1011
1012   Standard_CString& aSrc = (theSource >= GL_DEBUG_SOURCE_API
1013                         && theSource <= GL_DEBUG_SOURCE_OTHER)
1014                          ? THE_DBGMSG_SOURCES[theSource - GL_DEBUG_SOURCE_API]
1015                          : THE_DBGMSG_UNKNOWN;
1016   Standard_CString& aType = (theType >= GL_DEBUG_TYPE_ERROR
1017                          && theType <= GL_DEBUG_TYPE_OTHER)
1018                           ? THE_DBGMSG_TYPES[theType - GL_DEBUG_TYPE_ERROR]
1019                           : THE_DBGMSG_UNKNOWN;
1020   Standard_CString& aSev = theSeverity == GL_DEBUG_SEVERITY_HIGH
1021                          ? THE_DBGMSG_SEV_HIGH
1022                          : (theSeverity == GL_DEBUG_SEVERITY_MEDIUM
1023                           ? THE_DBGMSG_SEV_MEDIUM
1024                           : THE_DBGMSG_SEV_LOW);
1025   Message_Gravity aGrav = theSeverity == GL_DEBUG_SEVERITY_HIGH
1026                         ? Message_Alarm
1027                         : (theSeverity == GL_DEBUG_SEVERITY_MEDIUM
1028                          ? Message_Warning
1029                          : Message_Info);
1030
1031   TCollection_ExtendedString aMsg;
1032   aMsg += "TKOpenGl"; aMsg += aSrc;
1033   aMsg += " | Type: ";        aMsg += aType;
1034   aMsg += " | ID: ";          aMsg += (Standard_Integer )theId;
1035   aMsg += " | Severity: ";    aMsg += aSev;
1036   aMsg += " | Message:\n  ";
1037   aMsg += theMessage;
1038   Messenger()->Send (aMsg, aGrav);
1039 }
1040
1041 // =======================================================================
1042 // function : ExcludeMessage
1043 // purpose  :
1044 // ======================================================================
1045 Standard_Boolean OpenGl_Context::ExcludeMessage (const unsigned int theSource,
1046                                                  const unsigned int theId)
1047 {
1048   return theSource >= GL_DEBUG_SOURCE_API
1049       && theSource <= GL_DEBUG_SOURCE_OTHER
1050       && myFilters[theSource - GL_DEBUG_SOURCE_API].Add (theId);
1051 }
1052
1053 // =======================================================================
1054 // function : IncludeMessage
1055 // purpose  :
1056 // ======================================================================
1057 Standard_Boolean OpenGl_Context::IncludeMessage (const unsigned int theSource,
1058                                                  const unsigned int theId)
1059 {
1060   return theSource >= GL_DEBUG_SOURCE_API
1061       && theSource <= GL_DEBUG_SOURCE_OTHER
1062       && myFilters[theSource - GL_DEBUG_SOURCE_API].Remove (theId);
1063 }
1064
1065 // =======================================================================
1066 // function : checkWrongVersion
1067 // purpose  :
1068 // ======================================================================
1069 void OpenGl_Context::checkWrongVersion (const Standard_Integer theGlVerMajor,
1070                                         const Standard_Integer theGlVerMinor)
1071 {
1072   if (!IsGlGreaterEqual (theGlVerMajor, theGlVerMinor))
1073   {
1074     return;
1075   }
1076
1077   TCollection_ExtendedString aMsg = TCollection_ExtendedString()
1078     + "Error! OpenGL context reports version "
1079     + myGlVerMajor  + "." + myGlVerMinor
1080     + " but does not export required functions for "
1081     + theGlVerMajor + "." + theGlVerMinor;
1082   PushMessage (GL_DEBUG_SOURCE_APPLICATION,
1083                GL_DEBUG_TYPE_ERROR,
1084                0,
1085                GL_DEBUG_SEVERITY_HIGH,
1086                aMsg);
1087 }
1088
1089 // =======================================================================
1090 // function : init
1091 // purpose  :
1092 // =======================================================================
1093 void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
1094 {
1095   // read version
1096   myGlVerMajor = 0;
1097   myGlVerMinor = 0;
1098   myMaxMsaaSamples = 0;
1099   ReadGlVersion (myGlVerMajor, myGlVerMinor);
1100   myVendor = (const char* )::glGetString (GL_VENDOR);
1101   if (!caps->ffpEnable
1102    && !IsGlGreaterEqual (2, 0))
1103   {
1104     caps->ffpEnable = true;
1105     TCollection_ExtendedString aMsg =
1106       TCollection_ExtendedString("OpenGL driver is too old! Context info:\n")
1107                                + "    Vendor:   " + (const char* )::glGetString (GL_VENDOR)   + "\n"
1108                                + "    Renderer: " + (const char* )::glGetString (GL_RENDERER) + "\n"
1109                                + "    Version:  " + (const char* )::glGetString (GL_VERSION)  + "\n"
1110                                + "  Fallback using deprecated fixed-function pipeline.\n"
1111                                + "  Visualization might work incorrectly.\n"
1112                                  "  Consider upgrading the graphics driver.";
1113     PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
1114   }
1115
1116 #if defined(GL_ES_VERSION_2_0)
1117   (void )theIsCoreProfile;
1118   const bool isCoreProfile = false;
1119 #else
1120
1121   if (myVendor.Search ("NVIDIA") != -1)
1122   {
1123     // Buffer detailed info: Buffer object 1 (bound to GL_ARRAY_BUFFER_ARB, usage hint is GL_STATIC_DRAW)
1124     // will use VIDEO memory as the source for buffer object operations.
1125     ExcludeMessage (GL_DEBUG_SOURCE_API, 131185);
1126   }
1127   if (IsGlGreaterEqual (3, 0))
1128   {
1129     // retrieve auxiliary function in advance
1130     FindProc ("glGetStringi", myFuncs->glGetStringi);
1131   }
1132
1133   bool isCoreProfile = false;
1134   if (IsGlGreaterEqual (3, 2))
1135   {
1136     isCoreProfile = (theIsCoreProfile == Standard_True);
1137
1138     // detect Core profile
1139     if (!isCoreProfile)
1140     {
1141       GLint aProfile = 0;
1142       ::glGetIntegerv (GL_CONTEXT_PROFILE_MASK, &aProfile);
1143       isCoreProfile = (aProfile & GL_CONTEXT_CORE_PROFILE_BIT) != 0;
1144     }
1145   }
1146 #endif
1147
1148   core11     = NULL;
1149   if (!isCoreProfile)
1150   {
1151     core11 = (OpenGl_GlCore11* )(&(*myFuncs));
1152   }
1153   core11fwd  = (OpenGl_GlCore11Fwd* )(&(*myFuncs));
1154   core15     = NULL;
1155   core15fwd  = NULL;
1156   core20     = NULL;
1157   core20fwd  = NULL;
1158   core32     = NULL;
1159   core32back = NULL;
1160   core33     = NULL;
1161   core33back = NULL;
1162   core41     = NULL;
1163   core41back = NULL;
1164   core42     = NULL;
1165   core42back = NULL;
1166   core43     = NULL;
1167   core43back = NULL;
1168   core44     = NULL;
1169   core44back = NULL;
1170   arbTBO     = NULL;
1171   arbTboRGB32 = Standard_False;
1172   arbIns     = NULL;
1173   arbDbg     = NULL;
1174   arbFBO     = NULL;
1175   arbFBOBlit = NULL;
1176   extGS      = NULL;
1177   myDefaultVao = 0;
1178
1179 #if defined(GL_ES_VERSION_2_0)
1180
1181   hasTexRGBA8 = IsGlGreaterEqual (3, 0)
1182              || CheckExtension ("GL_OES_rgb8_rgba8");
1183   // NPOT textures has limited support within OpenGL ES 2.0
1184   // which are relaxed by OpenGL ES 3.0 or some extensions
1185   //arbNPTW     = IsGlGreaterEqual (3, 0)
1186   //           || CheckExtension ("GL_OES_texture_npot")
1187   //           || CheckExtension ("GL_NV_texture_npot_2D_mipmap");
1188   arbNPTW     = Standard_True;
1189   arbTexRG    = IsGlGreaterEqual (3, 0)
1190              || CheckExtension ("GL_EXT_texture_rg");
1191   extBgra     = CheckExtension ("GL_EXT_texture_format_BGRA8888");
1192   extAnis = CheckExtension ("GL_EXT_texture_filter_anisotropic");
1193   extPDS  = CheckExtension ("GL_OES_packed_depth_stencil");
1194
1195   core11fwd = (OpenGl_GlCore11Fwd* )(&(*myFuncs));
1196   if (IsGlGreaterEqual (2, 0))
1197   {
1198     // enable compatible functions
1199     core20    = (OpenGl_GlCore20*    )(&(*myFuncs));
1200     core20fwd = (OpenGl_GlCore20Fwd* )(&(*myFuncs));
1201     core15fwd = (OpenGl_GlCore15Fwd* )(&(*myFuncs));
1202     arbFBO    = (OpenGl_ArbFBO*      )(&(*myFuncs));
1203   }
1204   if (IsGlGreaterEqual (3, 0)
1205    && FindProc ("glBlitFramebuffer", myFuncs->glBlitFramebuffer))
1206   {
1207     arbFBOBlit = (OpenGl_ArbFBOBlit* )(&(*myFuncs));
1208   }
1209   extFragDepth = !IsGlGreaterEqual(3, 0)
1210                && CheckExtension ("GL_EXT_frag_depth");
1211   if (IsGlGreaterEqual (3, 1)
1212    && FindProc ("glTexStorage2DMultisample", myFuncs->glTexStorage2DMultisample))
1213   {
1214     // MSAA RenderBuffers have been defined in OpenGL ES 3.0,
1215     // but MSAA Textures - only in OpenGL ES 3.1+
1216     ::glGetIntegerv (GL_MAX_SAMPLES, &myMaxMsaaSamples);
1217   }
1218
1219   hasUintIndex = IsGlGreaterEqual (3, 0)
1220               || CheckExtension ("GL_OES_element_index_uint");
1221   hasHighp     = CheckExtension ("GL_OES_fragment_precision_high");
1222   GLint aRange[2] = {0, 0};
1223   GLint aPrec     = 0;
1224   ::glGetShaderPrecisionFormat (GL_FRAGMENT_SHADER, GL_HIGH_FLOAT, aRange, &aPrec);
1225   if (aPrec != 0)
1226   {
1227     hasHighp = Standard_True;
1228   }
1229
1230   arbTexFloat = IsGlGreaterEqual (3, 0)
1231              && FindProc ("glTexImage3D", myFuncs->glTexImage3D);
1232
1233   const Standard_Boolean hasTexBuffer32  = IsGlGreaterEqual (3, 2) && FindProc ("glTexBuffer", myFuncs->glTexBuffer);
1234   const Standard_Boolean hasExtTexBuffer = CheckExtension ("GL_EXT_texture_buffer") && FindProc ("glTexBufferEXT", myFuncs->glTexBuffer);
1235
1236   if (hasTexBuffer32 || hasExtTexBuffer)
1237   {
1238     arbTBO = reinterpret_cast<OpenGl_ArbTBO*> (myFuncs.get());
1239   }
1240
1241   // initialize debug context extension
1242   if (CheckExtension ("GL_KHR_debug"))
1243   {
1244     // this functionality become a part of OpenGL ES 3.2
1245     arbDbg = NULL;
1246     // According to GL_KHR_debug spec, all functions should have KHR suffix.
1247     // However, some implementations can export these functions without suffix.
1248     if (FindProc ("glDebugMessageControlKHR",  myFuncs->glDebugMessageControl)
1249      && FindProc ("glDebugMessageInsertKHR",   myFuncs->glDebugMessageInsert)
1250      && FindProc ("glDebugMessageCallbackKHR", myFuncs->glDebugMessageCallback)
1251      && FindProc ("glGetDebugMessageLogKHR",   myFuncs->glGetDebugMessageLog))
1252     {
1253       arbDbg = (OpenGl_ArbDbg* )(&(*myFuncs));
1254     }
1255
1256     if (arbDbg != NULL
1257      && caps->contextDebug)
1258     {
1259       // setup default callback
1260       myIsGlDebugCtx = Standard_True;
1261       arbDbg->glDebugMessageCallback (debugCallbackWrap, this);
1262       ::glEnable (GL_DEBUG_OUTPUT);
1263       if (caps->contextSyncDebug)
1264       {
1265         // note that some broken implementations (e.g. simulators) might generate error message on this call
1266         ::glEnable (GL_DEBUG_OUTPUT_SYNCHRONOUS);
1267       }
1268     }
1269   }
1270
1271 #else
1272
1273   myTexClamp = IsGlGreaterEqual (1, 2) ? GL_CLAMP_TO_EDGE : GL_CLAMP;
1274
1275   hasTexRGBA8 = Standard_True;
1276   arbNPTW     = CheckExtension ("GL_ARB_texture_non_power_of_two");
1277   arbTexFloat = IsGlGreaterEqual (3, 0)
1278              || CheckExtension ("GL_ARB_texture_float");
1279   extBgra     = CheckExtension ("GL_EXT_bgra");
1280   extAnis     = CheckExtension ("GL_EXT_texture_filter_anisotropic");
1281   extPDS      = CheckExtension ("GL_EXT_packed_depth_stencil");
1282   atiMem      = CheckExtension ("GL_ATI_meminfo");
1283   nvxMem      = CheckExtension ("GL_NVX_gpu_memory_info");
1284
1285   GLint aStereo = GL_FALSE;
1286   glGetIntegerv (GL_STEREO, &aStereo);
1287   myIsStereoBuffers = aStereo == 1;
1288
1289   // get number of maximum clipping planes
1290   glGetIntegerv (GL_MAX_CLIP_PLANES,  &myMaxClipPlanes);
1291 #endif
1292
1293   glGetIntegerv (GL_MAX_TEXTURE_SIZE, &myMaxTexDim);
1294
1295   if (extAnis)
1296   {
1297     glGetIntegerv (GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &myAnisoMax);
1298   }
1299
1300   myClippingState.Init (myMaxClipPlanes);
1301
1302 #if !defined(GL_ES_VERSION_2_0)
1303
1304   bool has12 = false;
1305   bool has13 = false;
1306   bool has14 = false;
1307   bool has15 = false;
1308   bool has20 = false;
1309   bool has21 = false;
1310   bool has30 = false;
1311   bool has31 = false;
1312   bool has32 = false;
1313   bool has33 = false;
1314   bool has40 = false;
1315   bool has41 = false;
1316   bool has42 = false;
1317   bool has43 = false;
1318   bool has44 = false;
1319
1320   //! Make record shorter to retrieve function pointer using variable with same name
1321   #define FindProcShort(theFunc) FindProc(#theFunc, myFuncs->theFunc)
1322
1323   // retrieve platform-dependent extensions
1324 #if defined(HAVE_EGL)
1325   //
1326 #elif defined(_WIN32)
1327   if (FindProcShort (wglGetExtensionsStringARB))
1328   {
1329     const char* aWglExts = myFuncs->wglGetExtensionsStringARB (wglGetCurrentDC());
1330     if (CheckExtension (aWglExts, "WGL_EXT_swap_control"))
1331     {
1332       FindProcShort (wglSwapIntervalEXT);
1333     }
1334     if (CheckExtension (aWglExts, "WGL_ARB_pixel_format"))
1335     {
1336       FindProcShort (wglChoosePixelFormatARB);
1337     }
1338     if (CheckExtension (aWglExts, "WGL_ARB_create_context_profile"))
1339     {
1340       FindProcShort (wglCreateContextAttribsARB);
1341     }
1342     if (CheckExtension (aWglExts, "WGL_NV_DX_interop"))
1343     {
1344       FindProcShort (wglDXSetResourceShareHandleNV);
1345       FindProcShort (wglDXOpenDeviceNV);
1346       FindProcShort (wglDXCloseDeviceNV);
1347       FindProcShort (wglDXRegisterObjectNV);
1348       FindProcShort (wglDXUnregisterObjectNV);
1349       FindProcShort (wglDXObjectAccessNV);
1350       FindProcShort (wglDXLockObjectsNV);
1351       FindProcShort (wglDXUnlockObjectsNV);
1352     }
1353     if (CheckExtension (aWglExts, "WGL_AMD_gpu_association"))
1354     {
1355       FindProcShort (wglGetGPUIDsAMD);
1356       FindProcShort (wglGetGPUInfoAMD);
1357       FindProcShort (wglGetContextGPUIDAMD);
1358     }
1359   }
1360 #elif defined(__APPLE__)
1361     //
1362 #else
1363     const char* aGlxExts = ::glXQueryExtensionsString ((Display* )myDisplay, DefaultScreen ((Display* )myDisplay));
1364     if (CheckExtension (aGlxExts, "GLX_EXT_swap_control"))
1365     {
1366       FindProcShort (glXSwapIntervalEXT);
1367     }
1368     if (CheckExtension (aGlxExts, "GLX_SGI_swap_control"))
1369     {
1370       FindProcShort (glXSwapIntervalSGI);
1371     }
1372     if (CheckExtension (aGlxExts, "GLX_MESA_query_renderer"))
1373     {
1374       FindProcShort (glXQueryRendererIntegerMESA);
1375       FindProcShort (glXQueryCurrentRendererIntegerMESA);
1376       FindProcShort (glXQueryRendererStringMESA);
1377       FindProcShort (glXQueryCurrentRendererStringMESA);
1378     }
1379     //extSwapTear = CheckExtension (aGlxExts, "GLX_EXT_swap_control_tear");
1380 #endif
1381
1382   // load OpenGL 1.2 new functions
1383   has12 = IsGlGreaterEqual (1, 2)
1384        && FindProcShort (glBlendColor)
1385        && FindProcShort (glBlendEquation)
1386        && FindProcShort (glDrawRangeElements)
1387        && FindProcShort (glTexImage3D)
1388        && FindProcShort (glTexSubImage3D)
1389        && FindProcShort (glCopyTexSubImage3D);
1390
1391   // load OpenGL 1.3 new functions
1392   has13 = IsGlGreaterEqual (1, 3)
1393        && FindProcShort (glActiveTexture)
1394        && FindProcShort (glSampleCoverage)
1395        && FindProcShort (glCompressedTexImage3D)
1396        && FindProcShort (glCompressedTexImage2D)
1397        && FindProcShort (glCompressedTexImage1D)
1398        && FindProcShort (glCompressedTexSubImage3D)
1399        && FindProcShort (glCompressedTexSubImage2D)
1400        && FindProcShort (glCompressedTexSubImage1D)
1401        && FindProcShort (glGetCompressedTexImage);
1402
1403   if (!isCoreProfile)
1404   {
1405     has13 = has13
1406        && FindProcShort (glClientActiveTexture)
1407        && FindProcShort (glMultiTexCoord1d)
1408        && FindProcShort (glMultiTexCoord1dv)
1409        && FindProcShort (glMultiTexCoord1f)
1410        && FindProcShort (glMultiTexCoord1fv)
1411        && FindProcShort (glMultiTexCoord1i)
1412        && FindProcShort (glMultiTexCoord1iv)
1413        && FindProcShort (glMultiTexCoord1s)
1414        && FindProcShort (glMultiTexCoord1sv)
1415        && FindProcShort (glMultiTexCoord2d)
1416        && FindProcShort (glMultiTexCoord2dv)
1417        && FindProcShort (glMultiTexCoord2f)
1418        && FindProcShort (glMultiTexCoord2fv)
1419        && FindProcShort (glMultiTexCoord2i)
1420        && FindProcShort (glMultiTexCoord2iv)
1421        && FindProcShort (glMultiTexCoord2s)
1422        && FindProcShort (glMultiTexCoord2sv)
1423        && FindProcShort (glMultiTexCoord3d)
1424        && FindProcShort (glMultiTexCoord3dv)
1425        && FindProcShort (glMultiTexCoord3f)
1426        && FindProcShort (glMultiTexCoord3fv)
1427        && FindProcShort (glMultiTexCoord3i)
1428        && FindProcShort (glMultiTexCoord3iv)
1429        && FindProcShort (glMultiTexCoord3s)
1430        && FindProcShort (glMultiTexCoord3sv)
1431        && FindProcShort (glMultiTexCoord4d)
1432        && FindProcShort (glMultiTexCoord4dv)
1433        && FindProcShort (glMultiTexCoord4f)
1434        && FindProcShort (glMultiTexCoord4fv)
1435        && FindProcShort (glMultiTexCoord4i)
1436        && FindProcShort (glMultiTexCoord4iv)
1437        && FindProcShort (glMultiTexCoord4s)
1438        && FindProcShort (glMultiTexCoord4sv)
1439        && FindProcShort (glLoadTransposeMatrixf)
1440        && FindProcShort (glLoadTransposeMatrixd)
1441        && FindProcShort (glMultTransposeMatrixf)
1442        && FindProcShort (glMultTransposeMatrixd);
1443   }
1444
1445   // load OpenGL 1.4 new functions
1446   has14 = IsGlGreaterEqual (1, 4)
1447        && FindProcShort (glBlendFuncSeparate)
1448        && FindProcShort (glMultiDrawArrays)
1449        && FindProcShort (glMultiDrawElements)
1450        && FindProcShort (glPointParameterf)
1451        && FindProcShort (glPointParameterfv)
1452        && FindProcShort (glPointParameteri)
1453        && FindProcShort (glPointParameteriv);
1454
1455   // load OpenGL 1.5 new functions
1456   has15 = IsGlGreaterEqual (1, 5)
1457        && FindProcShort (glGenQueries)
1458        && FindProcShort (glDeleteQueries)
1459        && FindProcShort (glIsQuery)
1460        && FindProcShort (glBeginQuery)
1461        && FindProcShort (glEndQuery)
1462        && FindProcShort (glGetQueryiv)
1463        && FindProcShort (glGetQueryObjectiv)
1464        && FindProcShort (glGetQueryObjectuiv)
1465        && FindProcShort (glBindBuffer)
1466        && FindProcShort (glDeleteBuffers)
1467        && FindProcShort (glGenBuffers)
1468        && FindProcShort (glIsBuffer)
1469        && FindProcShort (glBufferData)
1470        && FindProcShort (glBufferSubData)
1471        && FindProcShort (glGetBufferSubData)
1472        && FindProcShort (glMapBuffer)
1473        && FindProcShort (glUnmapBuffer)
1474        && FindProcShort (glGetBufferParameteriv)
1475        && FindProcShort (glGetBufferPointerv);
1476
1477   // load OpenGL 2.0 new functions
1478   has20 = IsGlGreaterEqual (2, 0)
1479        && FindProcShort (glBlendEquationSeparate)
1480        && FindProcShort (glDrawBuffers)
1481        && FindProcShort (glStencilOpSeparate)
1482        && FindProcShort (glStencilFuncSeparate)
1483        && FindProcShort (glStencilMaskSeparate)
1484        && FindProcShort (glAttachShader)
1485        && FindProcShort (glBindAttribLocation)
1486        && FindProcShort (glCompileShader)
1487        && FindProcShort (glCreateProgram)
1488        && FindProcShort (glCreateShader)
1489        && FindProcShort (glDeleteProgram)
1490        && FindProcShort (glDeleteShader)
1491        && FindProcShort (glDetachShader)
1492        && FindProcShort (glDisableVertexAttribArray)
1493        && FindProcShort (glEnableVertexAttribArray)
1494        && FindProcShort (glGetActiveAttrib)
1495        && FindProcShort (glGetActiveUniform)
1496        && FindProcShort (glGetAttachedShaders)
1497        && FindProcShort (glGetAttribLocation)
1498        && FindProcShort (glGetProgramiv)
1499        && FindProcShort (glGetProgramInfoLog)
1500        && FindProcShort (glGetShaderiv)
1501        && FindProcShort (glGetShaderInfoLog)
1502        && FindProcShort (glGetShaderSource)
1503        && FindProcShort (glGetUniformLocation)
1504        && FindProcShort (glGetUniformfv)
1505        && FindProcShort (glGetUniformiv)
1506        && FindProcShort (glGetVertexAttribdv)
1507        && FindProcShort (glGetVertexAttribfv)
1508        && FindProcShort (glGetVertexAttribiv)
1509        && FindProcShort (glGetVertexAttribPointerv)
1510        && FindProcShort (glIsProgram)
1511        && FindProcShort (glIsShader)
1512        && FindProcShort (glLinkProgram)
1513        && FindProcShort (glShaderSource)
1514        && FindProcShort (glUseProgram)
1515        && FindProcShort (glUniform1f)
1516        && FindProcShort (glUniform2f)
1517        && FindProcShort (glUniform3f)
1518        && FindProcShort (glUniform4f)
1519        && FindProcShort (glUniform1i)
1520        && FindProcShort (glUniform2i)
1521        && FindProcShort (glUniform3i)
1522        && FindProcShort (glUniform4i)
1523        && FindProcShort (glUniform1fv)
1524        && FindProcShort (glUniform2fv)
1525        && FindProcShort (glUniform3fv)
1526        && FindProcShort (glUniform4fv)
1527        && FindProcShort (glUniform1iv)
1528        && FindProcShort (glUniform2iv)
1529        && FindProcShort (glUniform3iv)
1530        && FindProcShort (glUniform4iv)
1531        && FindProcShort (glUniformMatrix2fv)
1532        && FindProcShort (glUniformMatrix3fv)
1533        && FindProcShort (glUniformMatrix4fv)
1534        && FindProcShort (glValidateProgram)
1535        && FindProcShort (glVertexAttrib1d)
1536        && FindProcShort (glVertexAttrib1dv)
1537        && FindProcShort (glVertexAttrib1f)
1538        && FindProcShort (glVertexAttrib1fv)
1539        && FindProcShort (glVertexAttrib1s)
1540        && FindProcShort (glVertexAttrib1sv)
1541        && FindProcShort (glVertexAttrib2d)
1542        && FindProcShort (glVertexAttrib2dv)
1543        && FindProcShort (glVertexAttrib2f)
1544        && FindProcShort (glVertexAttrib2fv)
1545        && FindProcShort (glVertexAttrib2s)
1546        && FindProcShort (glVertexAttrib2sv)
1547        && FindProcShort (glVertexAttrib3d)
1548        && FindProcShort (glVertexAttrib3dv)
1549        && FindProcShort (glVertexAttrib3f)
1550        && FindProcShort (glVertexAttrib3fv)
1551        && FindProcShort (glVertexAttrib3s)
1552        && FindProcShort (glVertexAttrib3sv)
1553        && FindProcShort (glVertexAttrib4Nbv)
1554        && FindProcShort (glVertexAttrib4Niv)
1555        && FindProcShort (glVertexAttrib4Nsv)
1556        && FindProcShort (glVertexAttrib4Nub)
1557        && FindProcShort (glVertexAttrib4Nubv)
1558        && FindProcShort (glVertexAttrib4Nuiv)
1559        && FindProcShort (glVertexAttrib4Nusv)
1560        && FindProcShort (glVertexAttrib4bv)
1561        && FindProcShort (glVertexAttrib4d)
1562        && FindProcShort (glVertexAttrib4dv)
1563        && FindProcShort (glVertexAttrib4f)
1564        && FindProcShort (glVertexAttrib4fv)
1565        && FindProcShort (glVertexAttrib4iv)
1566        && FindProcShort (glVertexAttrib4s)
1567        && FindProcShort (glVertexAttrib4sv)
1568        && FindProcShort (glVertexAttrib4ubv)
1569        && FindProcShort (glVertexAttrib4uiv)
1570        && FindProcShort (glVertexAttrib4usv)
1571        && FindProcShort (glVertexAttribPointer);
1572
1573   // load OpenGL 2.1 new functions
1574   has21 = IsGlGreaterEqual (2, 1)
1575        && FindProcShort (glUniformMatrix2x3fv)
1576        && FindProcShort (glUniformMatrix3x2fv)
1577        && FindProcShort (glUniformMatrix2x4fv)
1578        && FindProcShort (glUniformMatrix4x2fv)
1579        && FindProcShort (glUniformMatrix3x4fv)
1580        && FindProcShort (glUniformMatrix4x3fv);
1581
1582   // load GL_ARB_framebuffer_object (added to OpenGL 3.0 core)
1583   const bool hasFBO = (IsGlGreaterEqual (3, 0) || CheckExtension ("GL_ARB_framebuffer_object"))
1584        && FindProcShort (glIsRenderbuffer)
1585        && FindProcShort (glBindRenderbuffer)
1586        && FindProcShort (glDeleteRenderbuffers)
1587        && FindProcShort (glGenRenderbuffers)
1588        && FindProcShort (glRenderbufferStorage)
1589        && FindProcShort (glGetRenderbufferParameteriv)
1590        && FindProcShort (glIsFramebuffer)
1591        && FindProcShort (glBindFramebuffer)
1592        && FindProcShort (glDeleteFramebuffers)
1593        && FindProcShort (glGenFramebuffers)
1594        && FindProcShort (glCheckFramebufferStatus)
1595        && FindProcShort (glFramebufferTexture1D)
1596        && FindProcShort (glFramebufferTexture2D)
1597        && FindProcShort (glFramebufferTexture3D)
1598        && FindProcShort (glFramebufferRenderbuffer)
1599        && FindProcShort (glGetFramebufferAttachmentParameteriv)
1600        && FindProcShort (glGenerateMipmap)
1601        && FindProcShort (glBlitFramebuffer)
1602        && FindProcShort (glRenderbufferStorageMultisample)
1603        && FindProcShort (glFramebufferTextureLayer);
1604
1605   // load GL_ARB_vertex_array_object (added to OpenGL 3.0 core)
1606   const bool hasVAO = (IsGlGreaterEqual (3, 0) || CheckExtension ("GL_ARB_vertex_array_object"))
1607        && FindProcShort (glBindVertexArray)
1608        && FindProcShort (glDeleteVertexArrays)
1609        && FindProcShort (glGenVertexArrays)
1610        && FindProcShort (glIsVertexArray);
1611
1612   // load GL_ARB_map_buffer_range (added to OpenGL 3.0 core)
1613   const bool hasMapBufferRange = (IsGlGreaterEqual (3, 0) || CheckExtension ("GL_ARB_map_buffer_range"))
1614        && FindProcShort (glMapBufferRange)
1615        && FindProcShort (glFlushMappedBufferRange);
1616
1617   // load OpenGL 3.0 new functions
1618   has30 = IsGlGreaterEqual (3, 0)
1619        && hasFBO
1620        && hasVAO
1621        && hasMapBufferRange
1622        && FindProcShort (glColorMaski)
1623        && FindProcShort (glGetBooleani_v)
1624        && FindProcShort (glGetIntegeri_v)
1625        && FindProcShort (glEnablei)
1626        && FindProcShort (glDisablei)
1627        && FindProcShort (glIsEnabledi)
1628        && FindProcShort (glBeginTransformFeedback)
1629        && FindProcShort (glEndTransformFeedback)
1630        && FindProcShort (glBindBufferRange)
1631        && FindProcShort (glBindBufferBase)
1632        && FindProcShort (glTransformFeedbackVaryings)
1633        && FindProcShort (glGetTransformFeedbackVarying)
1634        && FindProcShort (glClampColor)
1635        && FindProcShort (glBeginConditionalRender)
1636        && FindProcShort (glEndConditionalRender)
1637        && FindProcShort (glVertexAttribIPointer)
1638        && FindProcShort (glGetVertexAttribIiv)
1639        && FindProcShort (glGetVertexAttribIuiv)
1640        && FindProcShort (glVertexAttribI1i)
1641        && FindProcShort (glVertexAttribI2i)
1642        && FindProcShort (glVertexAttribI3i)
1643        && FindProcShort (glVertexAttribI4i)
1644        && FindProcShort (glVertexAttribI1ui)
1645        && FindProcShort (glVertexAttribI2ui)
1646        && FindProcShort (glVertexAttribI3ui)
1647        && FindProcShort (glVertexAttribI4ui)
1648        && FindProcShort (glVertexAttribI1iv)
1649        && FindProcShort (glVertexAttribI2iv)
1650        && FindProcShort (glVertexAttribI3iv)
1651        && FindProcShort (glVertexAttribI4iv)
1652        && FindProcShort (glVertexAttribI1uiv)
1653        && FindProcShort (glVertexAttribI2uiv)
1654        && FindProcShort (glVertexAttribI3uiv)
1655        && FindProcShort (glVertexAttribI4uiv)
1656        && FindProcShort (glVertexAttribI4bv)
1657        && FindProcShort (glVertexAttribI4sv)
1658        && FindProcShort (glVertexAttribI4ubv)
1659        && FindProcShort (glVertexAttribI4usv)
1660        && FindProcShort (glGetUniformuiv)
1661        && FindProcShort (glBindFragDataLocation)
1662        && FindProcShort (glGetFragDataLocation)
1663        && FindProcShort (glUniform1ui)
1664        && FindProcShort (glUniform2ui)
1665        && FindProcShort (glUniform3ui)
1666        && FindProcShort (glUniform4ui)
1667        && FindProcShort (glUniform1uiv)
1668        && FindProcShort (glUniform2uiv)
1669        && FindProcShort (glUniform3uiv)
1670        && FindProcShort (glUniform4uiv)
1671        && FindProcShort (glTexParameterIiv)
1672        && FindProcShort (glTexParameterIuiv)
1673        && FindProcShort (glGetTexParameterIiv)
1674        && FindProcShort (glGetTexParameterIuiv)
1675        && FindProcShort (glClearBufferiv)
1676        && FindProcShort (glClearBufferuiv)
1677        && FindProcShort (glClearBufferfv)
1678        && FindProcShort (glClearBufferfi)
1679        && FindProcShort (glGetStringi);
1680
1681   // load GL_ARB_uniform_buffer_object (added to OpenGL 3.1 core)
1682   const bool hasUBO = (IsGlGreaterEqual (3, 1) || CheckExtension ("GL_ARB_uniform_buffer_object"))
1683        && FindProcShort (glGetUniformIndices)
1684        && FindProcShort (glGetActiveUniformsiv)
1685        && FindProcShort (glGetActiveUniformName)
1686        && FindProcShort (glGetUniformBlockIndex)
1687        && FindProcShort (glGetActiveUniformBlockiv)
1688        && FindProcShort (glGetActiveUniformBlockName)
1689        && FindProcShort (glUniformBlockBinding);
1690
1691   // load GL_ARB_copy_buffer (added to OpenGL 3.1 core)
1692   const bool hasCopyBufSubData = (IsGlGreaterEqual (3, 1) || CheckExtension ("GL_ARB_copy_buffer"))
1693        && FindProcShort (glCopyBufferSubData);
1694
1695   if (has30)
1696   {
1697     // NPOT textures are required by OpenGL 2.0 specifications
1698     // but doesn't hardware accelerated by some ancient OpenGL 2.1 hardware (GeForce FX, RadeOn 9700 etc.)
1699     arbNPTW  = Standard_True;
1700     arbTexRG = Standard_True;
1701   }
1702
1703   // load OpenGL 3.1 new functions
1704   has31 = IsGlGreaterEqual (3, 1)
1705        && hasUBO
1706        && hasCopyBufSubData
1707        && FindProcShort (glDrawArraysInstanced)
1708        && FindProcShort (glDrawElementsInstanced)
1709        && FindProcShort (glTexBuffer)
1710        && FindProcShort (glPrimitiveRestartIndex);
1711
1712   // load GL_ARB_draw_elements_base_vertex (added to OpenGL 3.2 core)
1713   const bool hasDrawElemsBaseVert = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_draw_elements_base_vertex"))
1714        && FindProcShort (glDrawElementsBaseVertex)
1715        && FindProcShort (glDrawRangeElementsBaseVertex)
1716        && FindProcShort (glDrawElementsInstancedBaseVertex)
1717        && FindProcShort (glMultiDrawElementsBaseVertex);
1718
1719   // load GL_ARB_provoking_vertex (added to OpenGL 3.2 core)
1720   const bool hasProvokingVert = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_provoking_vertex"))
1721        && FindProcShort (glProvokingVertex);
1722
1723   // load GL_ARB_sync (added to OpenGL 3.2 core)
1724   const bool hasSync = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_sync"))
1725        && FindProcShort (glFenceSync)
1726        && FindProcShort (glIsSync)
1727        && FindProcShort (glDeleteSync)
1728        && FindProcShort (glClientWaitSync)
1729        && FindProcShort (glWaitSync)
1730        && FindProcShort (glGetInteger64v)
1731        && FindProcShort (glGetSynciv);
1732
1733   // load GL_ARB_texture_multisample (added to OpenGL 3.2 core)
1734   const bool hasTextureMultisample = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_texture_multisample"))
1735        && FindProcShort (glTexImage2DMultisample)
1736        && FindProcShort (glTexImage3DMultisample)
1737        && FindProcShort (glGetMultisamplefv)
1738        && FindProcShort (glSampleMaski);
1739
1740   // load OpenGL 3.2 new functions
1741   has32 = IsGlGreaterEqual (3, 2)
1742        && hasDrawElemsBaseVert
1743        && hasProvokingVert
1744        && hasSync
1745        && hasTextureMultisample
1746        && FindProcShort (glGetInteger64i_v)
1747        && FindProcShort (glGetBufferParameteri64v)
1748        && FindProcShort (glFramebufferTexture);
1749
1750   // load GL_ARB_blend_func_extended (added to OpenGL 3.3 core)
1751   const bool hasBlendFuncExtended = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_blend_func_extended"))
1752        && FindProcShort (glBindFragDataLocationIndexed)
1753        && FindProcShort (glGetFragDataIndex);
1754
1755   // load GL_ARB_sampler_objects (added to OpenGL 3.3 core)
1756   const bool hasSamplerObjects = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_sampler_objects"))
1757        && FindProcShort (glGenSamplers)
1758        && FindProcShort (glDeleteSamplers)
1759        && FindProcShort (glIsSampler)
1760        && FindProcShort (glBindSampler)
1761        && FindProcShort (glSamplerParameteri)
1762        && FindProcShort (glSamplerParameteriv)
1763        && FindProcShort (glSamplerParameterf)
1764        && FindProcShort (glSamplerParameterfv)
1765        && FindProcShort (glSamplerParameterIiv)
1766        && FindProcShort (glSamplerParameterIuiv)
1767        && FindProcShort (glGetSamplerParameteriv)
1768        && FindProcShort (glGetSamplerParameterIiv)
1769        && FindProcShort (glGetSamplerParameterfv)
1770        && FindProcShort (glGetSamplerParameterIuiv);
1771
1772   // load GL_ARB_timer_query (added to OpenGL 3.3 core)
1773   const bool hasTimerQuery = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_timer_query"))
1774        && FindProcShort (glQueryCounter)
1775        && FindProcShort (glGetQueryObjecti64v)
1776        && FindProcShort (glGetQueryObjectui64v);
1777
1778   // load GL_ARB_vertex_type_2_10_10_10_rev (added to OpenGL 3.3 core)
1779   const bool hasVertType21010101rev = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_vertex_type_2_10_10_10_rev"))
1780        && FindProcShort (glVertexAttribP1ui)
1781        && FindProcShort (glVertexAttribP1uiv)
1782        && FindProcShort (glVertexAttribP2ui)
1783        && FindProcShort (glVertexAttribP2uiv)
1784        && FindProcShort (glVertexAttribP3ui)
1785        && FindProcShort (glVertexAttribP3uiv)
1786        && FindProcShort (glVertexAttribP4ui)
1787        && FindProcShort (glVertexAttribP4uiv);
1788
1789   if ( hasVertType21010101rev
1790    && !isCoreProfile)
1791   {
1792     // load deprecated functions
1793     const bool hasVertType21010101revExt =
1794           FindProcShort (glVertexP2ui)
1795        && FindProcShort (glVertexP2uiv)
1796        && FindProcShort (glVertexP3ui)
1797        && FindProcShort (glVertexP3uiv)
1798        && FindProcShort (glVertexP4ui)
1799        && FindProcShort (glVertexP4uiv)
1800        && FindProcShort (glTexCoordP1ui)
1801        && FindProcShort (glTexCoordP1uiv)
1802        && FindProcShort (glTexCoordP2ui)
1803        && FindProcShort (glTexCoordP2uiv)
1804        && FindProcShort (glTexCoordP3ui)
1805        && FindProcShort (glTexCoordP3uiv)
1806        && FindProcShort (glTexCoordP4ui)
1807        && FindProcShort (glTexCoordP4uiv)
1808        && FindProcShort (glMultiTexCoordP1ui)
1809        && FindProcShort (glMultiTexCoordP1uiv)
1810        && FindProcShort (glMultiTexCoordP2ui)
1811        && FindProcShort (glMultiTexCoordP2uiv)
1812        && FindProcShort (glMultiTexCoordP3ui)
1813        && FindProcShort (glMultiTexCoordP3uiv)
1814        && FindProcShort (glMultiTexCoordP4ui)
1815        && FindProcShort (glMultiTexCoordP4uiv)
1816        && FindProcShort (glNormalP3ui)
1817        && FindProcShort (glNormalP3uiv)
1818        && FindProcShort (glColorP3ui)
1819        && FindProcShort (glColorP3uiv)
1820        && FindProcShort (glColorP4ui)
1821        && FindProcShort (glColorP4uiv)
1822        && FindProcShort (glSecondaryColorP3ui)
1823        && FindProcShort (glSecondaryColorP3uiv);
1824     (void )hasVertType21010101revExt;
1825   }
1826
1827   // load OpenGL 3.3 extra functions
1828   has33 = IsGlGreaterEqual (3, 3)
1829        && hasBlendFuncExtended
1830        && hasSamplerObjects
1831        && hasTimerQuery
1832        && hasVertType21010101rev
1833        && FindProcShort (glVertexAttribDivisor);
1834
1835   // load GL_ARB_draw_indirect (added to OpenGL 4.0 core)
1836   const bool hasDrawIndirect = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_draw_indirect"))
1837        && FindProcShort (glDrawArraysIndirect)
1838        && FindProcShort (glDrawElementsIndirect);
1839
1840   // load GL_ARB_gpu_shader_fp64 (added to OpenGL 4.0 core)
1841   const bool hasShaderFP64 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_gpu_shader_fp64"))
1842        && FindProcShort (glUniform1d)
1843        && FindProcShort (glUniform2d)
1844        && FindProcShort (glUniform3d)
1845        && FindProcShort (glUniform4d)
1846        && FindProcShort (glUniform1dv)
1847        && FindProcShort (glUniform2dv)
1848        && FindProcShort (glUniform3dv)
1849        && FindProcShort (glUniform4dv)
1850        && FindProcShort (glUniformMatrix2dv)
1851        && FindProcShort (glUniformMatrix3dv)
1852        && FindProcShort (glUniformMatrix4dv)
1853        && FindProcShort (glUniformMatrix2x3dv)
1854        && FindProcShort (glUniformMatrix2x4dv)
1855        && FindProcShort (glUniformMatrix3x2dv)
1856        && FindProcShort (glUniformMatrix3x4dv)
1857        && FindProcShort (glUniformMatrix4x2dv)
1858        && FindProcShort (glUniformMatrix4x3dv)
1859        && FindProcShort (glGetUniformdv);
1860
1861   // load GL_ARB_shader_subroutine (added to OpenGL 4.0 core)
1862   const bool hasShaderSubroutine = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_shader_subroutine"))
1863        && FindProcShort (glGetSubroutineUniformLocation)
1864        && FindProcShort (glGetSubroutineIndex)
1865        && FindProcShort (glGetActiveSubroutineUniformiv)
1866        && FindProcShort (glGetActiveSubroutineUniformName)
1867        && FindProcShort (glGetActiveSubroutineName)
1868        && FindProcShort (glUniformSubroutinesuiv)
1869        && FindProcShort (glGetUniformSubroutineuiv)
1870        && FindProcShort (glGetProgramStageiv);
1871
1872   // load GL_ARB_tessellation_shader (added to OpenGL 4.0 core)
1873   const bool hasTessellationShader = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_tessellation_shader"))
1874        && FindProcShort (glPatchParameteri)
1875        && FindProcShort (glPatchParameterfv);
1876
1877   // load GL_ARB_transform_feedback2 (added to OpenGL 4.0 core)
1878   const bool hasTrsfFeedback2 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_transform_feedback2"))
1879        && FindProcShort (glBindTransformFeedback)
1880        && FindProcShort (glDeleteTransformFeedbacks)
1881        && FindProcShort (glGenTransformFeedbacks)
1882        && FindProcShort (glIsTransformFeedback)
1883        && FindProcShort (glPauseTransformFeedback)
1884        && FindProcShort (glResumeTransformFeedback)
1885        && FindProcShort (glDrawTransformFeedback);
1886
1887   // load GL_ARB_transform_feedback3 (added to OpenGL 4.0 core)
1888   const bool hasTrsfFeedback3 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_transform_feedback3"))
1889        && FindProcShort (glDrawTransformFeedbackStream)
1890        && FindProcShort (glBeginQueryIndexed)
1891        && FindProcShort (glEndQueryIndexed)
1892        && FindProcShort (glGetQueryIndexediv);
1893
1894   // load OpenGL 4.0 new functions
1895   has40 = IsGlGreaterEqual (4, 0)
1896       && hasDrawIndirect
1897       && hasShaderFP64
1898       && hasShaderSubroutine
1899       && hasTessellationShader
1900       && hasTrsfFeedback2
1901       && hasTrsfFeedback3
1902       && FindProcShort (glMinSampleShading)
1903       && FindProcShort (glBlendEquationi)
1904       && FindProcShort (glBlendEquationSeparatei)
1905       && FindProcShort (glBlendFunci)
1906       && FindProcShort (glBlendFuncSeparatei);
1907
1908   // load GL_ARB_ES2_compatibility (added to OpenGL 4.1 core)
1909   const bool hasES2Compatibility = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_ES2_compatibility"))
1910        && FindProcShort (glReleaseShaderCompiler)
1911        && FindProcShort (glShaderBinary)
1912        && FindProcShort (glGetShaderPrecisionFormat)
1913        && FindProcShort (glDepthRangef)
1914        && FindProcShort (glClearDepthf);
1915
1916   // load GL_ARB_get_program_binary (added to OpenGL 4.1 core)
1917   const bool hasGetProgramBinary = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_get_program_binary"))
1918        && FindProcShort (glGetProgramBinary)
1919        && FindProcShort (glProgramBinary)
1920        && FindProcShort (glProgramParameteri);
1921
1922
1923   // load GL_ARB_separate_shader_objects (added to OpenGL 4.1 core)
1924   const bool hasSeparateShaderObjects = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_separate_shader_objects"))
1925        && FindProcShort (glUseProgramStages)
1926        && FindProcShort (glActiveShaderProgram)
1927        && FindProcShort (glCreateShaderProgramv)
1928        && FindProcShort (glBindProgramPipeline)
1929        && FindProcShort (glDeleteProgramPipelines)
1930        && FindProcShort (glGenProgramPipelines)
1931        && FindProcShort (glIsProgramPipeline)
1932        && FindProcShort (glGetProgramPipelineiv)
1933        && FindProcShort (glProgramUniform1i)
1934        && FindProcShort (glProgramUniform1iv)
1935        && FindProcShort (glProgramUniform1f)
1936        && FindProcShort (glProgramUniform1fv)
1937        && FindProcShort (glProgramUniform1d)
1938        && FindProcShort (glProgramUniform1dv)
1939        && FindProcShort (glProgramUniform1ui)
1940        && FindProcShort (glProgramUniform1uiv)
1941        && FindProcShort (glProgramUniform2i)
1942        && FindProcShort (glProgramUniform2iv)
1943        && FindProcShort (glProgramUniform2f)
1944        && FindProcShort (glProgramUniform2fv)
1945        && FindProcShort (glProgramUniform2d)
1946        && FindProcShort (glProgramUniform2dv)
1947        && FindProcShort (glProgramUniform2ui)
1948        && FindProcShort (glProgramUniform2uiv)
1949        && FindProcShort (glProgramUniform3i)
1950        && FindProcShort (glProgramUniform3iv)
1951        && FindProcShort (glProgramUniform3f)
1952        && FindProcShort (glProgramUniform3fv)
1953        && FindProcShort (glProgramUniform3d)
1954        && FindProcShort (glProgramUniform3dv)
1955        && FindProcShort (glProgramUniform3ui)
1956        && FindProcShort (glProgramUniform3uiv)
1957        && FindProcShort (glProgramUniform4i)
1958        && FindProcShort (glProgramUniform4iv)
1959        && FindProcShort (glProgramUniform4f)
1960        && FindProcShort (glProgramUniform4fv)
1961        && FindProcShort (glProgramUniform4d)
1962        && FindProcShort (glProgramUniform4dv)
1963        && FindProcShort (glProgramUniform4ui)
1964        && FindProcShort (glProgramUniform4uiv)
1965        && FindProcShort (glProgramUniformMatrix2fv)
1966        && FindProcShort (glProgramUniformMatrix3fv)
1967        && FindProcShort (glProgramUniformMatrix4fv)
1968        && FindProcShort (glProgramUniformMatrix2dv)
1969        && FindProcShort (glProgramUniformMatrix3dv)
1970        && FindProcShort (glProgramUniformMatrix4dv)
1971        && FindProcShort (glProgramUniformMatrix2x3fv)
1972        && FindProcShort (glProgramUniformMatrix3x2fv)
1973        && FindProcShort (glProgramUniformMatrix2x4fv)
1974        && FindProcShort (glProgramUniformMatrix4x2fv)
1975        && FindProcShort (glProgramUniformMatrix3x4fv)
1976        && FindProcShort (glProgramUniformMatrix4x3fv)
1977        && FindProcShort (glProgramUniformMatrix2x3dv)
1978        && FindProcShort (glProgramUniformMatrix3x2dv)
1979        && FindProcShort (glProgramUniformMatrix2x4dv)
1980        && FindProcShort (glProgramUniformMatrix4x2dv)
1981        && FindProcShort (glProgramUniformMatrix3x4dv)
1982        && FindProcShort (glProgramUniformMatrix4x3dv)
1983        && FindProcShort (glValidateProgramPipeline)
1984        && FindProcShort (glGetProgramPipelineInfoLog);
1985
1986   // load GL_ARB_vertex_attrib_64bit (added to OpenGL 4.1 core)
1987   const bool hasVertAttrib64bit = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_vertex_attrib_64bit"))
1988        && FindProcShort (glVertexAttribL1d)
1989        && FindProcShort (glVertexAttribL2d)
1990        && FindProcShort (glVertexAttribL3d)
1991        && FindProcShort (glVertexAttribL4d)
1992        && FindProcShort (glVertexAttribL1dv)
1993        && FindProcShort (glVertexAttribL2dv)
1994        && FindProcShort (glVertexAttribL3dv)
1995        && FindProcShort (glVertexAttribL4dv)
1996        && FindProcShort (glVertexAttribLPointer)
1997        && FindProcShort (glGetVertexAttribLdv);
1998
1999   // load GL_ARB_viewport_array (added to OpenGL 4.1 core)
2000   const bool hasViewportArray = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_viewport_array"))
2001        && FindProcShort (glViewportArrayv)
2002        && FindProcShort (glViewportIndexedf)
2003        && FindProcShort (glViewportIndexedfv)
2004        && FindProcShort (glScissorArrayv)
2005        && FindProcShort (glScissorIndexed)
2006        && FindProcShort (glScissorIndexedv)
2007        && FindProcShort (glDepthRangeArrayv)
2008        && FindProcShort (glDepthRangeIndexed)
2009        && FindProcShort (glGetFloati_v)
2010        && FindProcShort (glGetDoublei_v);
2011
2012   has41 = IsGlGreaterEqual (4, 1)
2013        && hasES2Compatibility
2014        && hasGetProgramBinary
2015        && hasSeparateShaderObjects
2016        && hasVertAttrib64bit
2017        && hasViewportArray;
2018
2019   // load GL_ARB_base_instance (added to OpenGL 4.2 core)
2020   const bool hasBaseInstance = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_base_instance"))
2021        && FindProcShort (glDrawArraysInstancedBaseInstance)
2022        && FindProcShort (glDrawElementsInstancedBaseInstance)
2023        && FindProcShort (glDrawElementsInstancedBaseVertexBaseInstance);
2024
2025   // load GL_ARB_transform_feedback_instanced (added to OpenGL 4.2 core)
2026   const bool hasTrsfFeedbackInstanced = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_transform_feedback_instanced"))
2027        && FindProcShort (glDrawTransformFeedbackInstanced)
2028        && FindProcShort (glDrawTransformFeedbackStreamInstanced);
2029
2030   // load GL_ARB_internalformat_query (added to OpenGL 4.2 core)
2031   const bool hasInternalFormatQuery = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_internalformat_query"))
2032        && FindProcShort (glGetInternalformativ);
2033
2034   // load GL_ARB_shader_atomic_counters (added to OpenGL 4.2 core)
2035   const bool hasShaderAtomicCounters = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_shader_atomic_counters"))
2036        && FindProcShort (glGetActiveAtomicCounterBufferiv);
2037
2038   // load GL_ARB_shader_image_load_store (added to OpenGL 4.2 core)
2039   const bool hasShaderImgLoadStore = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_shader_image_load_store"))
2040        && FindProcShort (glBindImageTexture)
2041        && FindProcShort (glMemoryBarrier);
2042
2043   // load GL_ARB_texture_storage (added to OpenGL 4.2 core)
2044   const bool hasTextureStorage = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_texture_storage"))
2045        && FindProcShort (glTexStorage1D)
2046        && FindProcShort (glTexStorage2D)
2047        && FindProcShort (glTexStorage3D);
2048
2049   has42 = IsGlGreaterEqual (4, 2)
2050        && hasBaseInstance
2051        && hasTrsfFeedbackInstanced
2052        && hasInternalFormatQuery
2053        && hasShaderAtomicCounters
2054        && hasShaderImgLoadStore
2055        && hasTextureStorage;
2056
2057   has43 = IsGlGreaterEqual (4, 3)
2058        && FindProcShort (glClearBufferData)
2059        && FindProcShort (glClearBufferSubData)
2060        && FindProcShort (glDispatchCompute)
2061        && FindProcShort (glDispatchComputeIndirect)
2062        && FindProcShort (glCopyImageSubData)
2063        && FindProcShort (glFramebufferParameteri)
2064        && FindProcShort (glGetFramebufferParameteriv)
2065        && FindProcShort (glGetInternalformati64v)
2066        && FindProcShort (glInvalidateTexSubImage)
2067        && FindProcShort (glInvalidateTexImage)
2068        && FindProcShort (glInvalidateBufferSubData)
2069        && FindProcShort (glInvalidateBufferData)
2070        && FindProcShort (glInvalidateFramebuffer)
2071        && FindProcShort (glInvalidateSubFramebuffer)
2072        && FindProcShort (glMultiDrawArraysIndirect)
2073        && FindProcShort (glMultiDrawElementsIndirect)
2074        && FindProcShort (glGetProgramInterfaceiv)
2075        && FindProcShort (glGetProgramResourceIndex)
2076        && FindProcShort (glGetProgramResourceName)
2077        && FindProcShort (glGetProgramResourceiv)
2078        && FindProcShort (glGetProgramResourceLocation)
2079        && FindProcShort (glGetProgramResourceLocationIndex)
2080        && FindProcShort (glShaderStorageBlockBinding)
2081        && FindProcShort (glTexBufferRange)
2082        && FindProcShort (glTexStorage2DMultisample)
2083        && FindProcShort (glTexStorage3DMultisample)
2084        && FindProcShort (glTextureView)
2085        && FindProcShort (glBindVertexBuffer)
2086        && FindProcShort (glVertexAttribFormat)
2087        && FindProcShort (glVertexAttribIFormat)
2088        && FindProcShort (glVertexAttribLFormat)
2089        && FindProcShort (glVertexAttribBinding)
2090        && FindProcShort (glVertexBindingDivisor)
2091        && FindProcShort (glDebugMessageControl)
2092        && FindProcShort (glDebugMessageInsert)
2093        && FindProcShort (glDebugMessageCallback)
2094        && FindProcShort (glGetDebugMessageLog)
2095        && FindProcShort (glPushDebugGroup)
2096        && FindProcShort (glPopDebugGroup)
2097        && FindProcShort (glObjectLabel)
2098        && FindProcShort (glGetObjectLabel)
2099        && FindProcShort (glObjectPtrLabel)
2100        && FindProcShort (glGetObjectPtrLabel);
2101
2102   // load GL_ARB_clear_texture (added to OpenGL 4.4 core)
2103   bool arbTexClear = (IsGlGreaterEqual (4, 4) || CheckExtension ("GL_ARB_clear_texture"))
2104        && FindProcShort (glClearTexImage)
2105        && FindProcShort (glClearTexSubImage);
2106
2107   has44 = IsGlGreaterEqual (4, 4)
2108        && arbTexClear
2109        && FindProcShort (glBufferStorage)
2110        && FindProcShort (glBindBuffersBase)
2111        && FindProcShort (glBindBuffersRange)
2112        && FindProcShort (glBindTextures)
2113        && FindProcShort (glBindSamplers)
2114        && FindProcShort (glBindImageTextures)
2115        && FindProcShort (glBindVertexBuffers);
2116
2117   // initialize debug context extension
2118   if (CheckExtension ("GL_ARB_debug_output"))
2119   {
2120     arbDbg = NULL;
2121     if (has43)
2122     {
2123       arbDbg = (OpenGl_ArbDbg* )(&(*myFuncs));
2124     }
2125     else if (FindProc ("glDebugMessageControlARB",  myFuncs->glDebugMessageControl)
2126           && FindProc ("glDebugMessageInsertARB",   myFuncs->glDebugMessageInsert)
2127           && FindProc ("glDebugMessageCallbackARB", myFuncs->glDebugMessageCallback)
2128           && FindProc ("glGetDebugMessageLogARB",   myFuncs->glGetDebugMessageLog))
2129     {
2130       arbDbg = (OpenGl_ArbDbg* )(&(*myFuncs));
2131     }
2132
2133     if (arbDbg != NULL
2134      && caps->contextDebug)
2135     {
2136       // setup default callback
2137       myIsGlDebugCtx = Standard_True;
2138       arbDbg->glDebugMessageCallback (debugCallbackWrap, this);
2139       if (has43)
2140       {
2141         ::glEnable (GL_DEBUG_OUTPUT);
2142       }
2143       if (caps->contextSyncDebug)
2144       {
2145         ::glEnable (GL_DEBUG_OUTPUT_SYNCHRONOUS);
2146       }
2147     }
2148   }
2149
2150   // initialize TBO extension (ARB)
2151   if (!has31
2152    && CheckExtension ("GL_ARB_texture_buffer_object")
2153    && FindProc ("glTexBufferARB", myFuncs->glTexBuffer))
2154   {
2155     arbTBO = (OpenGl_ArbTBO* )(&(*myFuncs));
2156   }
2157   arbTboRGB32 = CheckExtension ("GL_ARB_texture_buffer_object_rgb32");
2158
2159   // initialize hardware instancing extension (ARB)
2160   if (!has31
2161    && CheckExtension ("GL_ARB_draw_instanced")
2162    && FindProc ("glDrawArraysInstancedARB",   myFuncs->glDrawArraysInstanced)
2163    && FindProc ("glDrawElementsInstancedARB", myFuncs->glDrawElementsInstanced))
2164   {
2165     arbIns = (OpenGl_ArbIns* )(&(*myFuncs));
2166   }
2167
2168   // initialize FBO extension (ARB)
2169   if (hasFBO)
2170   {
2171     arbFBO     = (OpenGl_ArbFBO*     )(&(*myFuncs));
2172     arbFBOBlit = (OpenGl_ArbFBOBlit* )(&(*myFuncs));
2173     extPDS = Standard_True; // extension for EXT, but part of ARB
2174   }
2175
2176   // initialize GS extension (EXT)
2177   if (CheckExtension ("GL_EXT_geometry_shader4")
2178    && FindProcShort (glProgramParameteriEXT))
2179   {
2180     extGS = (OpenGl_ExtGS* )(&(*myFuncs));
2181   }
2182
2183   // initialize bindless texture extension (ARB)
2184   if (CheckExtension ("GL_ARB_bindless_texture")
2185    && FindProcShort (glGetTextureHandleARB)
2186    && FindProcShort (glGetTextureSamplerHandleARB)
2187    && FindProcShort (glMakeTextureHandleResidentARB)
2188    && FindProcShort (glMakeTextureHandleNonResidentARB)
2189    && FindProcShort (glGetImageHandleARB)
2190    && FindProcShort (glMakeImageHandleResidentARB)
2191    && FindProcShort (glMakeImageHandleNonResidentARB)
2192    && FindProcShort (glUniformHandleui64ARB)
2193    && FindProcShort (glUniformHandleui64vARB)
2194    && FindProcShort (glProgramUniformHandleui64ARB)
2195    && FindProcShort (glProgramUniformHandleui64vARB)
2196    && FindProcShort (glIsTextureHandleResidentARB)
2197    && FindProcShort (glIsImageHandleResidentARB)
2198    && FindProcShort (glVertexAttribL1ui64ARB)
2199    && FindProcShort (glVertexAttribL1ui64vARB)
2200    && FindProcShort (glGetVertexAttribLui64vARB))
2201   {
2202     arbTexBindless = (OpenGl_ArbTexBindless* )(&(*myFuncs));
2203   }
2204
2205   if (!has12)
2206   {
2207     checkWrongVersion (1, 2);
2208     myGlVerMajor = 1;
2209     myGlVerMinor = 1;
2210     return;
2211   }
2212   else if (!has13)
2213   {
2214     checkWrongVersion (1, 3);
2215     myGlVerMajor = 1;
2216     myGlVerMinor = 2;
2217     return;
2218   }
2219   else if (!has14)
2220   {
2221     checkWrongVersion (1, 4);
2222     myGlVerMajor = 1;
2223     myGlVerMinor = 3;
2224     return;
2225   }
2226   else if (!has15)
2227   {
2228     checkWrongVersion (1, 5);
2229     myGlVerMajor = 1;
2230     myGlVerMinor = 4;
2231     return;
2232   }
2233   if (!isCoreProfile)
2234   {
2235     core15 = (OpenGl_GlCore15* )(&(*myFuncs));
2236   }
2237   core15fwd = (OpenGl_GlCore15Fwd* )(&(*myFuncs));
2238
2239   if (!has20)
2240   {
2241     checkWrongVersion (2, 0);
2242     myGlVerMajor = 1;
2243     myGlVerMinor = 5;
2244     return;
2245   }
2246
2247   const char* aGlslVer = (const char* )::glGetString (GL_SHADING_LANGUAGE_VERSION);
2248   if (aGlslVer == NULL
2249   || *aGlslVer == '\0')
2250   {
2251     // broken context has been detected
2252     TCollection_ExtendedString aMsg = TCollection_ExtendedString()
2253       + "Error! OpenGL context reports version "
2254       + myGlVerMajor  + "." + myGlVerMinor
2255       + " but reports wrong GLSL version";
2256     PushMessage (GL_DEBUG_SOURCE_APPLICATION,
2257                  GL_DEBUG_TYPE_ERROR,
2258                  0,
2259                  GL_DEBUG_SEVERITY_HIGH,
2260                  aMsg);
2261     myGlVerMajor = 1;
2262     myGlVerMinor = 5;
2263     return;
2264   }
2265
2266   if (!isCoreProfile)
2267   {
2268     core20  = (OpenGl_GlCore20*    )(&(*myFuncs));
2269   }
2270   core20fwd = (OpenGl_GlCore20Fwd* )(&(*myFuncs));
2271
2272   if (!has21)
2273   {
2274     checkWrongVersion (2, 1);
2275     myGlVerMajor = 2;
2276     myGlVerMinor = 0;
2277     return;
2278   }
2279
2280   if (!has30)
2281   {
2282     checkWrongVersion (3, 0);
2283     myGlVerMajor = 2;
2284     myGlVerMinor = 1;
2285     return;
2286   }
2287
2288   // MSAA RenderBuffers have been defined in OpenGL 3.0,
2289   // but MSAA Textures - only in OpenGL 3.2+
2290   if (!has32
2291    && CheckExtension ("GL_ARB_texture_multisample")
2292    && FindProcShort (glTexImage2DMultisample))
2293   {
2294     GLint aNbColorSamples = 0, aNbDepthSamples = 0;
2295     ::glGetIntegerv (GL_MAX_COLOR_TEXTURE_SAMPLES, &aNbColorSamples);
2296     ::glGetIntegerv (GL_MAX_DEPTH_TEXTURE_SAMPLES, &aNbDepthSamples);
2297     myMaxMsaaSamples = Min (aNbColorSamples, aNbDepthSamples);
2298   }
2299   if (!has43
2300    && CheckExtension ("GL_ARB_texture_storage_multisample")
2301    && FindProcShort (glTexStorage2DMultisample))
2302   {
2303     //
2304   }
2305
2306   if (!has31)
2307   {
2308     checkWrongVersion (3, 1);
2309     myGlVerMajor = 3;
2310     myGlVerMinor = 0;
2311     return;
2312   }
2313   arbTBO = (OpenGl_ArbTBO* )(&(*myFuncs));
2314   arbIns = (OpenGl_ArbIns* )(&(*myFuncs));
2315
2316   // check whether ray tracing mode is supported
2317   myHasRayTracing = has31
2318                  && arbTboRGB32
2319                  && arbFBOBlit  != NULL;
2320
2321   // check whether textures in ray tracing mode are supported
2322   myHasRayTracingTextures = myHasRayTracing
2323                          && arbTexBindless != NULL;
2324
2325   // check whether adaptive screen sampling in ray tracing mode is supported
2326   myHasRayTracingAdaptiveSampling = myHasRayTracing
2327                                  && has44
2328                                  && CheckExtension ("GL_NV_shader_atomic_float");
2329
2330   if (!has32)
2331   {
2332     checkWrongVersion (3, 2);
2333     myGlVerMajor = 3;
2334     myGlVerMinor = 1;
2335     return;
2336   }
2337   core32 = (OpenGl_GlCore32* )(&(*myFuncs));
2338   if (isCoreProfile)
2339   {
2340     core32->glGenVertexArrays (1, &myDefaultVao);
2341   }
2342   else
2343   {
2344     core32back = (OpenGl_GlCore32Back* )(&(*myFuncs));
2345   }
2346   ::glGetIntegerv (GL_MAX_SAMPLES, &myMaxMsaaSamples);
2347
2348   if (!has33)
2349   {
2350     checkWrongVersion (3, 3);
2351     myGlVerMajor = 3;
2352     myGlVerMinor = 2;
2353     return;
2354   }
2355   core33 = (OpenGl_GlCore33* )(&(*myFuncs));
2356   if (!isCoreProfile)
2357   {
2358     core33back = (OpenGl_GlCore33Back* )(&(*myFuncs));
2359   }
2360
2361   // initialize sampler object
2362   myTexSampler = new OpenGl_Sampler();
2363   myTexSampler->Init (*this);
2364
2365   if (!has40)
2366   {
2367     checkWrongVersion (4, 0);
2368     myGlVerMajor = 3;
2369     myGlVerMinor = 3;
2370     return;
2371   }
2372   arbTboRGB32 = Standard_True; // in core since OpenGL 4.0
2373
2374   if (!has41)
2375   {
2376     checkWrongVersion (4, 1);
2377     myGlVerMajor = 4;
2378     myGlVerMinor = 0;
2379     return;
2380   }
2381   core41 = (OpenGl_GlCore41* )(&(*myFuncs));
2382   if (!isCoreProfile)
2383   {
2384     core41back = (OpenGl_GlCore41Back* )(&(*myFuncs));
2385   }
2386
2387   if(!has42)
2388   {
2389     checkWrongVersion (4, 2);
2390     myGlVerMajor = 4;
2391     myGlVerMinor = 1;
2392     return;
2393   }
2394   core42 = (OpenGl_GlCore42* )(&(*myFuncs));
2395   if (!isCoreProfile)
2396   {
2397     core42back = (OpenGl_GlCore42Back* )(&(*myFuncs));
2398   }
2399
2400   if (!has43)
2401   {
2402     checkWrongVersion (4, 3);
2403     myGlVerMajor = 4;
2404     myGlVerMinor = 2;
2405     return;
2406   }
2407   core43 = (OpenGl_GlCore43* )(&(*myFuncs));
2408   if (!isCoreProfile)
2409   {
2410     core43back = (OpenGl_GlCore43Back* )(&(*myFuncs));
2411   }
2412
2413   if (!has44)
2414   {
2415     checkWrongVersion (4, 4);
2416     myGlVerMajor = 4;
2417     myGlVerMinor = 3;
2418     return;
2419   }
2420   core44 = (OpenGl_GlCore44* )(&(*myFuncs));
2421   if (!isCoreProfile)
2422   {
2423     core44back = (OpenGl_GlCore44Back* )(&(*myFuncs));
2424   }
2425 #endif
2426 }
2427
2428 // =======================================================================
2429 // function : MemoryInfo
2430 // purpose  :
2431 // =======================================================================
2432 Standard_Size OpenGl_Context::AvailableMemory() const
2433 {
2434 #if !defined(GL_ES_VERSION_2_0)
2435   if (atiMem)
2436   {
2437     // this is actually information for VBO pool
2438     // however because pools are mostly shared
2439     // it can be used for total GPU memory estimations
2440     GLint aMemInfo[4];
2441     aMemInfo[0] = 0;
2442     glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aMemInfo);
2443     // returned value is in KiB, however this maybe changed in future
2444     return Standard_Size(aMemInfo[0]) * 1024;
2445   }
2446   else if (nvxMem)
2447   {
2448     // current available dedicated video memory (in KiB), currently unused GPU memory
2449     GLint aMemInfo = 0;
2450     glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aMemInfo);
2451     return Standard_Size(aMemInfo) * 1024;
2452   }
2453 #endif
2454   return 0;
2455 }
2456
2457 // =======================================================================
2458 // function : MemoryInfo
2459 // purpose  :
2460 // =======================================================================
2461 TCollection_AsciiString OpenGl_Context::MemoryInfo() const
2462 {
2463   TColStd_IndexedDataMapOfStringString aDict;
2464   MemoryInfo (aDict);
2465
2466   TCollection_AsciiString aText;
2467   for (TColStd_IndexedDataMapOfStringString::Iterator anIter (aDict); anIter.More(); anIter.Next())
2468   {
2469     if (!aText.IsEmpty())
2470     {
2471       aText += "\n";
2472     }
2473     aText += TCollection_AsciiString("  ") + anIter.Key() + ": " + anIter.Value();
2474   }
2475   return aText;
2476 }
2477
2478 // =======================================================================
2479 // function : MemoryInfo
2480 // purpose  :
2481 // =======================================================================
2482 void OpenGl_Context::MemoryInfo (TColStd_IndexedDataMapOfStringString& theDict) const
2483 {
2484 #if defined(GL_ES_VERSION_2_0)
2485   (void )theDict;
2486 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
2487   GLint aGlRendId = 0;
2488   CGLGetParameter (CGLGetCurrentContext(), kCGLCPCurrentRendererID, &aGlRendId);
2489
2490   CGLRendererInfoObj  aRendObj = NULL;
2491   CGOpenGLDisplayMask aDispMask = CGDisplayIDToOpenGLDisplayMask (kCGDirectMainDisplay);
2492   GLint aRendNb = 0;
2493   CGLQueryRendererInfo (aDispMask, &aRendObj, &aRendNb);
2494   for (GLint aRendIter = 0; aRendIter < aRendNb; ++aRendIter)
2495   {
2496     GLint aRendId = 0;
2497     if (CGLDescribeRenderer (aRendObj, aRendIter, kCGLRPRendererID, &aRendId) != kCGLNoError
2498      || aRendId != aGlRendId)
2499     {
2500       continue;
2501     }
2502
2503     //kCGLRPVideoMemoryMegabytes   = 131;
2504     //kCGLRPTextureMemoryMegabytes = 132;
2505     GLint aVMem = 0;
2506   #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
2507     if (CGLDescribeRenderer(aRendObj, aRendIter, kCGLRPVideoMemoryMegabytes, &aVMem) == kCGLNoError)
2508     {
2509       addInfo (theDict, "GPU memory",         TCollection_AsciiString() + aVMem + " MiB");
2510     }
2511     if (CGLDescribeRenderer(aRendObj, aRendIter, kCGLRPTextureMemoryMegabytes, &aVMem) == kCGLNoError)
2512     {
2513       addInfo (theDict, "GPU Texture memory", TCollection_AsciiString() + aVMem + " MiB");
2514     }
2515   #else
2516     if (CGLDescribeRenderer(aRendObj, aRendIter, kCGLRPVideoMemory, &aVMem) == kCGLNoError)
2517     {
2518       addInfo (theDict, "GPU memory",         TCollection_AsciiString() + (aVMem / (1024 * 1024)) + " MiB");
2519     }
2520     if (CGLDescribeRenderer(aRendObj, aRendIter, kCGLRPTextureMemory, &aVMem) == kCGLNoError)
2521     {
2522       addInfo (theDict, "GPU Texture memory", TCollection_AsciiString() + (aVMem / (1024 * 1024)) + " MiB");
2523     }
2524   #endif
2525   }
2526 #endif
2527
2528 #if !defined(GL_ES_VERSION_2_0)
2529   if (atiMem)
2530   {
2531     GLint aValues[4];
2532     memset (aValues, 0, sizeof(aValues));
2533     glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aValues);
2534
2535     // total memory free in the pool
2536     addInfo (theDict, "GPU free memory",    TCollection_AsciiString() + (aValues[0] / 1024) + " MiB");
2537
2538     if (aValues[1] != aValues[0])
2539     {
2540       // largest available free block in the pool
2541       addInfo (theDict, "Largest free block", TCollection_AsciiString() + (aValues[1] / 1024) + " MiB");
2542     }
2543     if (aValues[2] != aValues[0])
2544     {
2545       // total auxiliary memory free
2546       addInfo (theDict, "Free auxiliary memory", TCollection_AsciiString() + (aValues[2] / 1024) + " MiB");
2547     }
2548   }
2549   else if (nvxMem)
2550   {
2551     //current available dedicated video memory (in KiB), currently unused GPU memory
2552     GLint aValue = 0;
2553     glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aValue);
2554     addInfo (theDict, "GPU free memory", TCollection_AsciiString() + (aValue / 1024) + " MiB");
2555
2556     // dedicated video memory, total size (in KiB) of the GPU memory
2557     GLint aDedicated = 0;
2558     glGetIntegerv (GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &aDedicated);
2559     addInfo (theDict, "GPU memory", TCollection_AsciiString() + (aDedicated / 1024) + " MiB");
2560
2561     // total available memory, total size (in KiB) of the memory available for allocations
2562     glGetIntegerv (GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &aValue);
2563     if (aValue != aDedicated)
2564     {
2565       // different only for special configurations
2566       addInfo (theDict, "Total memory", TCollection_AsciiString() + (aValue / 1024) + " MiB");
2567     }
2568   }
2569 #if defined(_WIN32)
2570   else if (myFuncs->wglGetGPUInfoAMD != NULL
2571         && myFuncs->wglGetContextGPUIDAMD != NULL)
2572   {
2573     GLuint aTotalMemMiB = 0;
2574     UINT anAmdId = myFuncs->wglGetContextGPUIDAMD ((HGLRC )myGContext);
2575     if (anAmdId != 0)
2576     {
2577       if (myFuncs->wglGetGPUInfoAMD (anAmdId, WGL_GPU_RAM_AMD, GL_UNSIGNED_INT, sizeof(aTotalMemMiB), &aTotalMemMiB) > 0)
2578       {
2579         addInfo (theDict, "GPU memory", TCollection_AsciiString() + (int )aTotalMemMiB + " MiB");
2580       }
2581     }
2582   }
2583 #endif
2584 #endif
2585
2586 #if !defined(GL_ES_VERSION_2_0) && !defined(__APPLE__) && !defined(_WIN32)
2587   // GLX_RENDERER_VENDOR_ID_MESA
2588   if (myFuncs->glXQueryCurrentRendererIntegerMESA != NULL)
2589   {
2590     unsigned int aVMemMiB = 0;
2591     if (myFuncs->glXQueryCurrentRendererIntegerMESA (GLX_RENDERER_VIDEO_MEMORY_MESA, &aVMemMiB) != False)
2592     {
2593       addInfo (theDict, "GPU memory", TCollection_AsciiString() + int(aVMemMiB) + " MiB");
2594     }
2595   }
2596 #endif
2597 }
2598
2599 // =======================================================================
2600 // function : DiagnosticInfo
2601 // purpose  :
2602 // =======================================================================
2603 void OpenGl_Context::DiagnosticInformation (TColStd_IndexedDataMapOfStringString& theDict,
2604                                             Graphic3d_DiagnosticInfo theFlags) const
2605 {
2606   if ((theFlags & Graphic3d_DiagnosticInfo_NativePlatform) != 0)
2607   {
2608   #if defined(HAVE_EGL)
2609     addInfo (theDict, "EGLVersion",    ::eglQueryString ((Aspect_Display)myDisplay, EGL_VERSION));
2610     addInfo (theDict, "EGLVendor",     ::eglQueryString ((Aspect_Display)myDisplay, EGL_VENDOR));
2611     addInfo (theDict, "EGLClientAPIs", ::eglQueryString ((Aspect_Display)myDisplay, EGL_CLIENT_APIS));
2612     if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0)
2613     {
2614       addInfo (theDict, "EGLExtensions", ::eglQueryString ((Aspect_Display)myDisplay, EGL_EXTENSIONS));
2615     }
2616   #elif defined(_WIN32)
2617     if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0
2618      && myFuncs->wglGetExtensionsStringARB != NULL)
2619     {
2620       const char* aWglExts = myFuncs->wglGetExtensionsStringARB ((HDC )myWindowDC);
2621       addInfo (theDict, "WGLExtensions", aWglExts);
2622     }
2623   #elif defined(__APPLE__)
2624     //
2625   #else
2626     Display* aDisplay = (Display*)myDisplay;
2627     const int aScreen = DefaultScreen(aDisplay);
2628     addInfo (theDict, "GLXDirectRendering", ::glXIsDirect (aDisplay, (GLXContext )myGContext) ? "Yes" : "No");
2629     addInfo (theDict, "GLXVendor",  ::glXQueryServerString (aDisplay, aScreen, GLX_VENDOR));
2630     addInfo (theDict, "GLXVersion", ::glXQueryServerString (aDisplay, aScreen, GLX_VERSION));
2631     if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0)
2632     {
2633       const char* aGlxExts = ::glXQueryExtensionsString (aDisplay, aScreen);
2634       addInfo(theDict, "GLXExtensions", aGlxExts);
2635     }
2636
2637     addInfo (theDict, "GLXClientVendor",  ::glXGetClientString (aDisplay, GLX_VENDOR));
2638     addInfo (theDict, "GLXClientVersion", ::glXGetClientString (aDisplay, GLX_VERSION));
2639     if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0)
2640     {
2641       addInfo (theDict, "GLXClientExtensions", ::glXGetClientString (aDisplay, GLX_EXTENSIONS));
2642     }
2643   #endif
2644   }
2645
2646   if ((theFlags & Graphic3d_DiagnosticInfo_Device) != 0)
2647   {
2648     addInfo (theDict, "GLvendor",    (const char*)::glGetString (GL_VENDOR));
2649     addInfo (theDict, "GLdevice",    (const char*)::glGetString (GL_RENDERER));
2650     addInfo (theDict, "GLversion",   (const char*)::glGetString (GL_VERSION));
2651     addInfo (theDict, "GLSLversion", (const char*)::glGetString (GL_SHADING_LANGUAGE_VERSION));
2652     if (myIsGlDebugCtx)
2653     {
2654       addInfo (theDict, "GLdebug", "ON");
2655     }
2656   }
2657
2658   if ((theFlags & Graphic3d_DiagnosticInfo_Limits) != 0)
2659   {
2660     addInfo (theDict, "Max texture size", TCollection_AsciiString(myMaxTexDim));
2661     addInfo (theDict, "Max MSAA samples", TCollection_AsciiString(myMaxMsaaSamples));
2662   }
2663
2664   if ((theFlags & Graphic3d_DiagnosticInfo_FrameBuffer) != 0)
2665   {
2666     GLint aViewport[4] = {};
2667     ::glGetIntegerv (GL_VIEWPORT, aViewport);
2668     addInfo (theDict, "Viewport", TCollection_AsciiString() + aViewport[2] + "x" + aViewport[3]);
2669   }
2670
2671   if ((theFlags & Graphic3d_DiagnosticInfo_Memory) != 0)
2672   {
2673     MemoryInfo (theDict);
2674   }
2675
2676   if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0)
2677   {
2678   #if !defined(GL_ES_VERSION_2_0)
2679     if (IsGlGreaterEqual (3, 0)
2680      && myFuncs->glGetStringi != NULL)
2681     {
2682       TCollection_AsciiString anExtList;
2683       GLint anExtNb = 0;
2684       ::glGetIntegerv (GL_NUM_EXTENSIONS, &anExtNb);
2685       for (GLint anIter = 0; anIter < anExtNb; ++anIter)
2686       {
2687         const char* anExtension = (const char*)myFuncs->glGetStringi (GL_EXTENSIONS, (GLuint)anIter);
2688         if (!anExtList.IsEmpty())
2689         {
2690           anExtList += " ";
2691         }
2692         anExtList += anExtension;
2693       }
2694       addInfo(theDict, "GLextensions", anExtList);
2695     }
2696     else
2697   #endif
2698     {
2699       addInfo (theDict, "GLextensions", (const char*)::glGetString (GL_EXTENSIONS));
2700     }
2701   }
2702 }
2703
2704 // =======================================================================
2705 // function : GetResource
2706 // purpose  :
2707 // =======================================================================
2708 const Handle(OpenGl_Resource)& OpenGl_Context::GetResource (const TCollection_AsciiString& theKey) const
2709 {
2710   return mySharedResources->IsBound (theKey) ? mySharedResources->Find (theKey) : NULL_GL_RESOURCE;
2711 }
2712
2713 // =======================================================================
2714 // function : ShareResource
2715 // purpose  :
2716 // =======================================================================
2717 Standard_Boolean OpenGl_Context::ShareResource (const TCollection_AsciiString& theKey,
2718                                                 const Handle(OpenGl_Resource)& theResource)
2719 {
2720   if (theKey.IsEmpty() || theResource.IsNull())
2721   {
2722     return Standard_False;
2723   }
2724   return mySharedResources->Bind (theKey, theResource);
2725 }
2726
2727 // =======================================================================
2728 // function : ReleaseResource
2729 // purpose  :
2730 // =======================================================================
2731 void OpenGl_Context::ReleaseResource (const TCollection_AsciiString& theKey,
2732                                       const Standard_Boolean         theToDelay)
2733 {
2734   if (!mySharedResources->IsBound (theKey))
2735   {
2736     return;
2737   }
2738   auto& aRes = mySharedResources->Find (theKey);
2739   if (aRes->GetRefCount() > 1)
2740   {
2741     return;
2742   }
2743
2744   if (theToDelay)
2745   {
2746     myDelayed->Bind (theKey, 1);
2747   }
2748   else
2749   {
2750     aRes->Release (this);
2751     mySharedResources->UnBind (theKey);
2752   }
2753 }
2754
2755 // =======================================================================
2756 // function : ReleaseDelayed
2757 // purpose  :
2758 // =======================================================================
2759 void OpenGl_Context::ReleaseDelayed()
2760 {
2761   // release queued elements
2762   while (!myUnusedResources->IsEmpty())
2763   {
2764     myUnusedResources->First()->Release (this);
2765     myUnusedResources->RemoveFirst();
2766   }
2767
2768   // release delayed shared resources
2769   NCollection_Vector<TCollection_AsciiString> aDeadList;
2770   for (NCollection_DataMap<TCollection_AsciiString, Standard_Integer>::Iterator anIter (*myDelayed);
2771        anIter.More(); anIter.Next())
2772   {
2773     if (++anIter.ChangeValue() <= 2)
2774     {
2775       continue; // postpone release one more frame to ensure noone use it periodically
2776     }
2777
2778     const TCollection_AsciiString& aKey = anIter.Key();
2779     if (!mySharedResources->IsBound (aKey))
2780     {
2781       // mixed unshared strategy delayed/undelayed was used!
2782       aDeadList.Append (aKey);
2783       continue;
2784     }
2785
2786     auto& aRes = mySharedResources->ChangeFind (aKey);
2787     if (aRes->GetRefCount() > 1)
2788     {
2789       // should be only 1 instance in mySharedResources
2790       // if not - resource was reused again
2791       aDeadList.Append (aKey);
2792       continue;
2793     }
2794
2795     // release resource if no one requiested it more than 2 redraw calls
2796     aRes->Release (this);
2797     mySharedResources->UnBind (aKey);
2798     aDeadList.Append (aKey);
2799   }
2800
2801   for (Standard_Integer anIter = 0; anIter < aDeadList.Length(); ++anIter)
2802   {
2803     myDelayed->UnBind (aDeadList.Value (anIter));
2804   }
2805 }
2806
2807 // =======================================================================
2808 // function : BindProgram
2809 // purpose  :
2810 // =======================================================================
2811 Standard_Boolean OpenGl_Context::BindProgram (const Handle(OpenGl_ShaderProgram)& theProgram)
2812 {
2813   if (core20fwd == NULL)
2814   {
2815     return Standard_False;
2816   }
2817   else if (myActiveProgram == theProgram)
2818   {
2819     return Standard_True;
2820   }
2821
2822   if (theProgram.IsNull()
2823   || !theProgram->IsValid())
2824   {
2825     if (!myActiveProgram.IsNull())
2826     {
2827       core20fwd->glUseProgram (OpenGl_ShaderProgram::NO_PROGRAM);
2828       myActiveProgram.Nullify();
2829     }
2830     return Standard_False;
2831   }
2832
2833   myActiveProgram = theProgram;
2834   core20fwd->glUseProgram (theProgram->ProgramId());
2835   return Standard_True;
2836 }
2837
2838 // =======================================================================
2839 // function : BindDefaultVao
2840 // purpose  :
2841 // =======================================================================
2842 void OpenGl_Context::BindDefaultVao()
2843 {
2844 #if !defined(GL_ES_VERSION_2_0)
2845   if (myDefaultVao == 0
2846    || core32 == NULL)
2847   {
2848     return;
2849   }
2850
2851   core32->glBindVertexArray (myDefaultVao);
2852 #endif
2853 }
2854
2855 // =======================================================================
2856 // function : SetDefaultFrameBuffer
2857 // purpose  :
2858 // =======================================================================
2859 Handle(OpenGl_FrameBuffer) OpenGl_Context::SetDefaultFrameBuffer (const Handle(OpenGl_FrameBuffer)& theFbo)
2860 {
2861   Handle(OpenGl_FrameBuffer) aFbo = myDefaultFbo;
2862   myDefaultFbo = theFbo;
2863   return aFbo;
2864 }
2865
2866 // =======================================================================
2867 // function : SetShadingMaterial
2868 // purpose  :
2869 // =======================================================================
2870 void OpenGl_Context::SetShadingMaterial (const OpenGl_AspectFace* theAspect,
2871                                          const Handle(Graphic3d_PresentationAttributes)& theHighlight,
2872                                          const Standard_Boolean theUseDepthWrite)
2873 {
2874   const Handle(Graphic3d_AspectFillArea3d)& anAspect = (!theHighlight.IsNull() && !theHighlight->BasicFillAreaAspect().IsNull())
2875                                                       ?  theHighlight->BasicFillAreaAspect()
2876                                                       :  theAspect->Aspect();
2877
2878   const bool toDistinguish = anAspect->Distinguish();
2879   const bool toMapTexture  = anAspect->ToMapTexture();
2880   const Graphic3d_MaterialAspect& aMatFrontSrc = anAspect->FrontMaterial();
2881   const Graphic3d_MaterialAspect& aMatBackSrc  = toDistinguish
2882                                                ? anAspect->BackMaterial()
2883                                                : aMatFrontSrc;
2884   const Quantity_Color& aFrontIntColor = anAspect->InteriorColor();
2885   const Quantity_Color& aBackIntColor  = toDistinguish
2886                                        ? anAspect->BackInteriorColor()
2887                                        : aFrontIntColor;
2888
2889   myMatFront.Init (aMatFrontSrc, aFrontIntColor);
2890   if (toDistinguish)
2891   {
2892     myMatBack.Init (aMatBackSrc, aBackIntColor);
2893   }
2894   else
2895   {
2896     myMatBack = myMatFront;
2897   }
2898
2899   // handling transparency
2900   float aTranspFront = aMatFrontSrc.Transparency();
2901   float aTranspBack  = aMatBackSrc .Transparency();
2902   if (!theHighlight.IsNull()
2903     && theHighlight->BasicFillAreaAspect().IsNull())
2904   {
2905     myMatFront.SetColor (theHighlight->ColorRGBA());
2906     myMatBack .SetColor (theHighlight->ColorRGBA());
2907     aTranspFront = theHighlight->Transparency();
2908     aTranspBack  = theHighlight->Transparency();
2909   }
2910   {
2911     GLboolean aDepthMask = GL_TRUE;
2912     if (aTranspFront != 0.0f
2913      || aTranspBack  != 0.0f)
2914     {
2915       // render transparent
2916       myMatFront.Diffuse.a() = 1.0f - aTranspFront;
2917       myMatBack .Diffuse.a() = 1.0f - aTranspBack;
2918       glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2919       glEnable (GL_BLEND);
2920       aDepthMask = GL_FALSE;
2921     }
2922     else
2923     {
2924       // render opaque
2925       glBlendFunc (GL_ONE, GL_ZERO);
2926       glDisable (GL_BLEND);
2927     }
2928     if (theUseDepthWrite)
2929     {
2930       glDepthMask (aDepthMask);
2931     }
2932   }
2933
2934   // do not update material properties in case of zero reflection mode,
2935   // because GL lighting will be disabled by OpenGl_PrimitiveArray::DrawArray() anyway.
2936   if (theAspect->IsNoLighting())
2937   {
2938     return;
2939   }
2940
2941   if (myMatFront    == myShaderManager->MaterialState().FrontMaterial()
2942    && myMatBack     == myShaderManager->MaterialState().BackMaterial()
2943    && toDistinguish == myShaderManager->MaterialState().ToDistinguish()
2944    && toMapTexture  == myShaderManager->MaterialState().ToMapTexture())
2945   {
2946     return;
2947   }
2948
2949   myShaderManager->UpdateMaterialStateTo (myMatFront, myMatBack, toDistinguish, toMapTexture);
2950 }
2951
2952 // =======================================================================
2953 // function : SetColor4fv
2954 // purpose  :
2955 // =======================================================================
2956 void OpenGl_Context::SetColor4fv (const OpenGl_Vec4& theColor)
2957 {
2958   if (!myActiveProgram.IsNull())
2959   {
2960     myActiveProgram->SetUniform (this, myActiveProgram->GetStateLocation (OpenGl_OCCT_COLOR), theColor);
2961   }
2962 #if !defined(GL_ES_VERSION_2_0)
2963   else if (core11 != NULL)
2964   {
2965     core11->glColor4fv (theColor.GetData());
2966   }
2967 #endif
2968 }
2969
2970 // =======================================================================
2971 // function : SetTypeOfLine
2972 // purpose  :
2973 // =======================================================================
2974 void OpenGl_Context::SetTypeOfLine (const Aspect_TypeOfLine  theType,
2975                                     const Standard_ShortReal theFactor)
2976 {
2977   Standard_Integer aPattern = 0xFFFF;
2978   switch (theType)
2979   {
2980     case Aspect_TOL_DASH:
2981     {
2982       aPattern = 0xFFC0;
2983       break;
2984     }
2985     case Aspect_TOL_DOT:
2986     {
2987       aPattern = 0xCCCC;
2988       break;
2989     }
2990     case Aspect_TOL_DOTDASH:
2991     {
2992       aPattern = 0xFF18;
2993       break;
2994     }
2995     case Aspect_TOL_EMPTY:
2996     case Aspect_TOL_SOLID:
2997     {
2998       aPattern = 0xFFFF;
2999       break;
3000     }
3001     case Aspect_TOL_USERDEFINED:
3002     {
3003       aPattern = 0xFF24;
3004       break;
3005     }
3006   }
3007
3008   if (!myActiveProgram.IsNull())
3009   {
3010     myActiveProgram->SetUniform (this, "uPattern", aPattern);
3011     myActiveProgram->SetUniform (this, "uFactor",  theFactor);
3012     return;
3013   }
3014
3015 #if !defined(GL_ES_VERSION_2_0)
3016   if (aPattern != 0xFFFF)
3017   {
3018   #ifdef HAVE_GL2PS
3019     if (IsFeedback())
3020     {
3021       gl2psEnable (GL2PS_LINE_STIPPLE);
3022     }
3023   #endif
3024
3025     if (core11 != NULL)
3026     {
3027       core11fwd->glEnable (GL_LINE_STIPPLE);
3028
3029       core11->glLineStipple (static_cast<GLint>    (theFactor),
3030                              static_cast<GLushort> (aPattern));
3031     }
3032   }
3033   else
3034   {
3035     if (core11 != NULL)
3036     {
3037       core11fwd->glDisable (GL_LINE_STIPPLE);
3038     }
3039
3040   #ifdef HAVE_GL2PS
3041     if (IsFeedback())
3042     {
3043       gl2psDisable (GL2PS_LINE_STIPPLE);
3044     }
3045   #endif
3046   }
3047 #endif
3048 }
3049
3050 // =======================================================================
3051 // function : SetLineWidth
3052 // purpose  :
3053 // =======================================================================
3054 void OpenGl_Context::SetLineWidth (const Standard_ShortReal theWidth)
3055 {
3056   if (core11 != NULL)
3057   {
3058     // glLineWidth() is still defined within Core Profile, but has no effect with values != 1.0f
3059     core11fwd->glLineWidth (theWidth * myResolutionRatio);
3060   }
3061 #ifdef HAVE_GL2PS
3062   if (IsFeedback())
3063   {
3064     gl2psLineWidth (theWidth);
3065   }
3066 #endif
3067 }
3068
3069 // =======================================================================
3070 // function : SetTextureMatrix
3071 // purpose  :
3072 // =======================================================================
3073 void OpenGl_Context::SetTextureMatrix (const Handle(Graphic3d_TextureParams)& theParams)
3074 {
3075   if (theParams.IsNull())
3076   {
3077     return;
3078   }
3079   else if (!myActiveProgram.IsNull())
3080   {
3081     const GLint aUniLoc = myActiveProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_TRSF2D);
3082     if (aUniLoc == OpenGl_ShaderProgram::INVALID_LOCATION)
3083     {
3084       return;
3085     }
3086
3087     // pack transformation parameters
3088     OpenGl_Vec4 aTrsf[2];
3089     aTrsf[0].xy() = theParams->Translation();
3090     aTrsf[0].zw() = theParams->Scale();
3091     aTrsf[1].x()  = std::sin (-theParams->Rotation() * static_cast<float> (M_PI / 180.0));
3092     aTrsf[1].y()  = std::cos (-theParams->Rotation() * static_cast<float> (M_PI / 180.0));
3093     myActiveProgram->SetUniform (this, aUniLoc, 2, aTrsf);
3094     return;
3095   }
3096
3097 #if !defined(GL_ES_VERSION_2_0)
3098   if (core11 != NULL)
3099   {
3100     GLint aMatrixMode = GL_TEXTURE;
3101     ::glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
3102
3103     core11->glMatrixMode (GL_TEXTURE);
3104     OpenGl_Mat4 aTextureMat;
3105     const Graphic3d_Vec2& aScale = theParams->Scale();
3106     const Graphic3d_Vec2& aTrans = theParams->Translation();
3107     Graphic3d_TransformUtils::Scale     (aTextureMat,  aScale.x(),  aScale.y(), 1.0f);
3108     Graphic3d_TransformUtils::Translate (aTextureMat, -aTrans.x(), -aTrans.y(), 0.0f);
3109     Graphic3d_TransformUtils::Rotate    (aTextureMat, -theParams->Rotation(), 0.0f, 0.0f, 1.0f);
3110     core11->glLoadMatrixf (aTextureMat);
3111     core11->glMatrixMode (aMatrixMode);
3112   }
3113 #endif
3114 }
3115
3116 // =======================================================================
3117 // function : SetPointSize
3118 // purpose  :
3119 // =======================================================================
3120 void OpenGl_Context::SetPointSize (const Standard_ShortReal theSize)
3121 {
3122   if (!myActiveProgram.IsNull())
3123   {
3124     myActiveProgram->SetUniform (this, myActiveProgram->GetStateLocation (OpenGl_OCCT_POINT_SIZE), theSize);
3125   #if !defined(GL_ES_VERSION_2_0)
3126     //myContext->core11fwd->glEnable (GL_VERTEX_PROGRAM_POINT_SIZE);
3127   #endif
3128   }
3129 #if !defined(GL_ES_VERSION_2_0)
3130   //else
3131   {
3132     core11fwd->glPointSize (theSize);
3133     if (core20fwd != NULL)
3134     {
3135       //myContext->core11fwd->glDisable (GL_VERTEX_PROGRAM_POINT_SIZE);
3136     }
3137   }
3138 #endif
3139 }
3140
3141 // =======================================================================
3142 // function : SetPointSpriteOrigin
3143 // purpose  :
3144 // =======================================================================
3145 void OpenGl_Context::SetPointSpriteOrigin()
3146 {
3147 #if !defined(GL_ES_VERSION_2_0)
3148   if (core15fwd == NULL)
3149   {
3150     return;
3151   }
3152
3153   const int aNewState = !myActiveProgram.IsNull() ? GL_UPPER_LEFT : GL_LOWER_LEFT;
3154   if (myPointSpriteOrig != aNewState)
3155   {
3156     myPointSpriteOrig = aNewState;
3157     core15fwd->glPointParameteri (GL_POINT_SPRITE_COORD_ORIGIN, aNewState);
3158   }
3159 #endif
3160 }
3161
3162 // =======================================================================
3163 // function : SetGlNormalizeEnabled
3164 // purpose  :
3165 // =======================================================================
3166 Standard_Boolean OpenGl_Context::SetGlNormalizeEnabled (Standard_Boolean isEnabled)
3167 {
3168   if (isEnabled == myIsGlNormalizeEnabled)
3169   {
3170     return myIsGlNormalizeEnabled;
3171   }
3172
3173   Standard_Boolean anOldGlNormalize = myIsGlNormalizeEnabled;
3174
3175   myIsGlNormalizeEnabled = isEnabled;
3176
3177 #if !defined(GL_ES_VERSION_2_0)
3178   if (core11 != NULL)
3179   {
3180     if (isEnabled)
3181     {
3182       ::glEnable  (GL_NORMALIZE);
3183     }
3184     else
3185     {
3186       ::glDisable (GL_NORMALIZE);
3187     }
3188   }
3189 #endif
3190
3191   return anOldGlNormalize;
3192 }
3193
3194 // =======================================================================
3195 // function : SetPolygonMode
3196 // purpose  :
3197 // =======================================================================
3198 Standard_Integer OpenGl_Context::SetPolygonMode (const Standard_Integer theMode)
3199 {
3200   if (myPolygonMode == theMode)
3201   {
3202     return myPolygonMode;
3203   }
3204
3205   const Standard_Integer anOldPolygonMode = myPolygonMode;
3206
3207   myPolygonMode = theMode;
3208
3209 #if !defined(GL_ES_VERSION_2_0)
3210   ::glPolygonMode (GL_FRONT_AND_BACK, (GLenum)theMode);
3211 #endif
3212
3213   return anOldPolygonMode;
3214 }
3215
3216 // =======================================================================
3217 // function : SetPolygonHatchEnabled
3218 // purpose  :
3219 // =======================================================================
3220 bool OpenGl_Context::SetPolygonHatchEnabled (const bool theIsEnabled)
3221 {
3222   if (myHatchStyles.IsNull())
3223   {
3224     return false;
3225   }
3226   else if (myHatchStyles->IsEnabled() == theIsEnabled)
3227   {
3228     return theIsEnabled;
3229   }
3230
3231   return myHatchStyles->SetEnabled (this, theIsEnabled);
3232 }
3233
3234 // =======================================================================
3235 // function : SetPolygonHatchStyle
3236 // purpose  :
3237 // =======================================================================
3238 Standard_Integer OpenGl_Context::SetPolygonHatchStyle (const Handle(Graphic3d_HatchStyle)& theStyle)
3239 {
3240   if (theStyle.IsNull())
3241   {
3242     return 0;
3243   }
3244
3245   if (myHatchStyles.IsNull())
3246   {
3247     if (!GetResource ("OpenGl_LineAttributes", myHatchStyles))
3248     {
3249       // share and register for release once the resource is no longer used
3250       myHatchStyles = new OpenGl_LineAttributes();
3251       ShareResource ("OpenGl_LineAttributes", myHatchStyles);
3252     }
3253   }
3254   if (myHatchStyles->TypeOfHatch() == theStyle->HatchType())
3255   {
3256     return theStyle->HatchType();
3257   }
3258
3259   return myHatchStyles->SetTypeOfHatch (this, theStyle);
3260 }
3261
3262 // =======================================================================
3263 // function : ApplyModelWorldMatrix
3264 // purpose  :
3265 // =======================================================================
3266 void OpenGl_Context::ApplyModelWorldMatrix()
3267 {
3268   if (myShaderManager->ModelWorldState().ModelWorldMatrix() != ModelWorldState.Current())
3269   {
3270     myShaderManager->UpdateModelWorldStateTo (ModelWorldState.Current());
3271   }
3272 }
3273
3274 // =======================================================================
3275 // function : ApplyWorldViewMatrix
3276 // purpose  :
3277 // =======================================================================
3278 void OpenGl_Context::ApplyWorldViewMatrix()
3279 {
3280   if (myShaderManager->ModelWorldState().ModelWorldMatrix() != THE_IDENTITY_MATRIX)
3281   {
3282     myShaderManager->UpdateModelWorldStateTo (THE_IDENTITY_MATRIX);
3283   }
3284   if (myShaderManager->WorldViewState().WorldViewMatrix() != WorldViewState.Current())
3285   {
3286     myShaderManager->UpdateWorldViewStateTo (WorldViewState.Current());
3287   }
3288 }
3289
3290 // =======================================================================
3291 // function : ApplyModelViewMatrix
3292 // purpose  :
3293 // =======================================================================
3294 void OpenGl_Context::ApplyModelViewMatrix()
3295 {
3296   if (myShaderManager->ModelWorldState().ModelWorldMatrix() != ModelWorldState.Current())
3297   {
3298     myShaderManager->UpdateModelWorldStateTo (ModelWorldState.Current());
3299   }
3300   if (myShaderManager->WorldViewState().WorldViewMatrix() != WorldViewState.Current())
3301   {
3302     myShaderManager->UpdateWorldViewStateTo  (WorldViewState.Current());
3303   }
3304 }
3305
3306 // =======================================================================
3307 // function : ApplyProjectionMatrix
3308 // purpose  :
3309 // =======================================================================
3310 void OpenGl_Context::ApplyProjectionMatrix()
3311 {
3312   if (myShaderManager->ProjectionState().ProjectionMatrix() != ProjectionState.Current())
3313   {
3314     myShaderManager->UpdateProjectionStateTo (ProjectionState.Current());
3315   }
3316 }
3317
3318 // =======================================================================
3319 // function : EnableFeatures
3320 // purpose  :
3321 // =======================================================================
3322 void OpenGl_Context::EnableFeatures() const
3323 {
3324   //
3325 }
3326
3327 // =======================================================================
3328 // function : DisableFeatures
3329 // purpose  :
3330 // =======================================================================
3331 void OpenGl_Context::DisableFeatures() const
3332 {
3333 #if !defined(GL_ES_VERSION_2_0)
3334   glPixelTransferi (GL_MAP_COLOR, GL_FALSE);
3335 #endif
3336
3337   /*
3338   * Disable stuff that's likely to slow down glDrawPixels.
3339   * (Omit as much of this as possible, when you know in advance
3340   * that the OpenGL state will already be set correctly.)
3341   */
3342   glDisable(GL_DITHER);
3343   glDisable(GL_BLEND);
3344   glDisable(GL_DEPTH_TEST);
3345   glDisable(GL_TEXTURE_2D);
3346   glDisable(GL_STENCIL_TEST);
3347
3348 #if !defined(GL_ES_VERSION_2_0)
3349   glDisable(GL_LIGHTING);
3350   glDisable(GL_ALPHA_TEST);
3351   glDisable(GL_FOG);
3352   glDisable(GL_LOGIC_OP);
3353   glDisable(GL_TEXTURE_1D);
3354
3355   glPixelTransferi(GL_MAP_COLOR, GL_FALSE);
3356   glPixelTransferi(GL_RED_SCALE, 1);
3357   glPixelTransferi(GL_RED_BIAS, 0);
3358   glPixelTransferi(GL_GREEN_SCALE, 1);
3359   glPixelTransferi(GL_GREEN_BIAS, 0);
3360   glPixelTransferi(GL_BLUE_SCALE, 1);
3361   glPixelTransferi(GL_BLUE_BIAS, 0);
3362   glPixelTransferi(GL_ALPHA_SCALE, 1);
3363   glPixelTransferi(GL_ALPHA_BIAS, 0);
3364
3365   /*
3366   * Disable extensions that could slow down glDrawPixels.
3367   * (Actually, you should check for the presence of the proper
3368   * extension before making these calls.  I've omitted that
3369   * code for simplicity.)
3370   */
3371
3372   if ((myGlVerMajor >= 1) && (myGlVerMinor >= 2))
3373   {
3374 #ifdef GL_EXT_convolution
3375     if (CheckExtension ("GL_CONVOLUTION_1D_EXT"))
3376       glDisable(GL_CONVOLUTION_1D_EXT);
3377
3378     if (CheckExtension ("GL_CONVOLUTION_2D_EXT"))
3379       glDisable(GL_CONVOLUTION_2D_EXT);
3380
3381     if (CheckExtension ("GL_SEPARABLE_2D_EXT"))
3382       glDisable(GL_SEPARABLE_2D_EXT);
3383 #endif
3384
3385 #ifdef GL_EXT_histogram
3386     if (CheckExtension ("GL_SEPARABLE_2D_EXT"))
3387       glDisable(GL_HISTOGRAM_EXT);
3388
3389     if (CheckExtension ("GL_MINMAX_EXT"))
3390       glDisable(GL_MINMAX_EXT);
3391 #endif
3392
3393 #ifdef GL_EXT_texture3D
3394     if (CheckExtension ("GL_TEXTURE_3D_EXT"))
3395       glDisable(GL_TEXTURE_3D_EXT);
3396 #endif
3397   }
3398 #endif
3399 }