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