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