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