01413d530b373486ab43e5d24568c843ad35f85d
[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 #ifndef __EMSCRIPTEN__ // latest Emscripten does not pretend having / simulating mapping buffer functions
1581   const bool hasMapBufferRange = IsGlGreaterEqual (3, 0)
1582        && FindProcShort (glMapBufferRange)
1583        && FindProcShort (glUnmapBuffer)
1584        && FindProcShort (glGetBufferPointerv)
1585        && FindProcShort (glFlushMappedBufferRange);
1586 #endif
1587
1588   // load OpenGL ES 3.0 new functions
1589   const bool has30es = IsGlGreaterEqual (3, 0)
1590        && hasVAO
1591     #ifndef __EMSCRIPTEN__
1592        && hasMapBufferRange
1593     #endif
1594        && hasInstanced
1595        && arbSamplerObject != NULL
1596        && arbFBOBlit != NULL
1597        && FindProcShort (glReadBuffer)
1598        && FindProcShort (glDrawRangeElements)
1599        && FindProcShort (glTexImage3D)
1600        && FindProcShort (glTexSubImage3D)
1601        && FindProcShort (glCopyTexSubImage3D)
1602        && FindProcShort (glCompressedTexImage3D)
1603        && FindProcShort (glCompressedTexSubImage3D)
1604        && FindProcShort (glGenQueries)
1605        && FindProcShort (glDeleteQueries)
1606        && FindProcShort (glIsQuery)
1607        && FindProcShort (glBeginQuery)
1608        && FindProcShort (glEndQuery)
1609        && FindProcShort (glGetQueryiv)
1610        && FindProcShort (glGetQueryObjectuiv)
1611        && FindProcShort (glDrawBuffers)
1612        && FindProcShort (glUniformMatrix2x3fv)
1613        && FindProcShort (glUniformMatrix3x2fv)
1614        && FindProcShort (glUniformMatrix2x4fv)
1615        && FindProcShort (glUniformMatrix4x2fv)
1616        && FindProcShort (glUniformMatrix3x4fv)
1617        && FindProcShort (glUniformMatrix4x3fv)
1618        && FindProcShort (glRenderbufferStorageMultisample)
1619        && FindProcShort (glFramebufferTextureLayer)
1620        && FindProcShort (glGetIntegeri_v)
1621        && FindProcShort (glBeginTransformFeedback)
1622        && FindProcShort (glEndTransformFeedback)
1623        && FindProcShort (glBindBufferRange)
1624        && FindProcShort (glBindBufferBase)
1625        && FindProcShort (glTransformFeedbackVaryings)
1626        && FindProcShort (glGetTransformFeedbackVarying)
1627        && FindProcShort (glVertexAttribIPointer)
1628        && FindProcShort (glGetVertexAttribIiv)
1629        && FindProcShort (glGetVertexAttribIuiv)
1630        && FindProcShort (glVertexAttribI4i)
1631        && FindProcShort (glVertexAttribI4ui)
1632        && FindProcShort (glVertexAttribI4iv)
1633        && FindProcShort (glVertexAttribI4uiv)
1634        && FindProcShort (glGetUniformuiv)
1635        && FindProcShort (glGetFragDataLocation)
1636        && FindProcShort (glUniform1ui)
1637        && FindProcShort (glUniform2ui)
1638        && FindProcShort (glUniform3ui)
1639        && FindProcShort (glUniform4ui)
1640        && FindProcShort (glUniform1uiv)
1641        && FindProcShort (glUniform2uiv)
1642        && FindProcShort (glUniform3uiv)
1643        && FindProcShort (glUniform4uiv)
1644        && FindProcShort (glClearBufferiv)
1645        && FindProcShort (glClearBufferuiv)
1646        && FindProcShort (glClearBufferfv)
1647        && FindProcShort (glClearBufferfi)
1648        && FindProcShort (glGetStringi)
1649        && FindProcShort (glCopyBufferSubData)
1650        && FindProcShort (glGetUniformIndices)
1651        && FindProcShort (glGetActiveUniformsiv)
1652        && FindProcShort (glGetUniformBlockIndex)
1653        && FindProcShort (glGetActiveUniformBlockiv)
1654        && FindProcShort (glGetActiveUniformBlockName)
1655        && FindProcShort (glUniformBlockBinding)
1656        && FindProcShort (glFenceSync)
1657        && FindProcShort (glIsSync)
1658        && FindProcShort (glDeleteSync)
1659        && FindProcShort (glClientWaitSync)
1660        && FindProcShort (glWaitSync)
1661        && FindProcShort (glGetInteger64v)
1662        && FindProcShort (glGetSynciv)
1663        && FindProcShort (glGetInteger64i_v)
1664        && FindProcShort (glGetBufferParameteri64v)
1665        && FindProcShort (glBindTransformFeedback)
1666        && FindProcShort (glDeleteTransformFeedbacks)
1667        && FindProcShort (glGenTransformFeedbacks)
1668        && FindProcShort (glIsTransformFeedback)
1669        && FindProcShort (glPauseTransformFeedback)
1670        && FindProcShort (glResumeTransformFeedback)
1671        && FindProcShort (glGetProgramBinary)
1672        && FindProcShort (glProgramBinary)
1673        && FindProcShort (glProgramParameteri)
1674        && FindProcShort (glInvalidateFramebuffer)
1675        && FindProcShort (glInvalidateSubFramebuffer)
1676        && FindProcShort (glTexStorage2D)
1677        && FindProcShort (glTexStorage3D)
1678        && FindProcShort (glGetInternalformativ);
1679   if (!has30es)
1680   {
1681     checkWrongVersion (3, 0, aLastFailedProc);
1682   }
1683   else
1684   {
1685     core30    = (OpenGl_GlCore30*    )(&(*myFuncs));
1686     core30fwd = (OpenGl_GlCore30Fwd* )(&(*myFuncs));
1687     hasGetBufferData = true;
1688   }
1689
1690   // load OpenGL ES 3.1 new functions
1691   const bool has31es = IsGlGreaterEqual (3, 1)
1692        && has30es
1693        && FindProcShort (glDispatchCompute)
1694        && FindProcShort (glDispatchComputeIndirect)
1695        && FindProcShort (glDrawArraysIndirect)
1696        && FindProcShort (glDrawElementsIndirect)
1697        && FindProcShort (glFramebufferParameteri)
1698        && FindProcShort (glGetFramebufferParameteriv)
1699        && FindProcShort (glGetProgramInterfaceiv)
1700        && FindProcShort (glGetProgramResourceIndex)
1701        && FindProcShort (glGetProgramResourceName)
1702        && FindProcShort (glGetProgramResourceiv)
1703        && FindProcShort (glGetProgramResourceLocation)
1704        && FindProcShort (glUseProgramStages)
1705        && FindProcShort (glActiveShaderProgram)
1706        && FindProcShort (glCreateShaderProgramv)
1707        && FindProcShort (glBindProgramPipeline)
1708        && FindProcShort (glDeleteProgramPipelines)
1709        && FindProcShort (glGenProgramPipelines)
1710        && FindProcShort (glIsProgramPipeline)
1711        && FindProcShort (glGetProgramPipelineiv)
1712        && FindProcShort (glProgramUniform1i)
1713        && FindProcShort (glProgramUniform2i)
1714        && FindProcShort (glProgramUniform3i)
1715        && FindProcShort (glProgramUniform4i)
1716        && FindProcShort (glProgramUniform1ui)
1717        && FindProcShort (glProgramUniform2ui)
1718        && FindProcShort (glProgramUniform3ui)
1719        && FindProcShort (glProgramUniform4ui)
1720        && FindProcShort (glProgramUniform1f)
1721        && FindProcShort (glProgramUniform2f)
1722        && FindProcShort (glProgramUniform3f)
1723        && FindProcShort (glProgramUniform4f)
1724        && FindProcShort (glProgramUniform1iv)
1725        && FindProcShort (glProgramUniform2iv)
1726        && FindProcShort (glProgramUniform3iv)
1727        && FindProcShort (glProgramUniform4iv)
1728        && FindProcShort (glProgramUniform1uiv)
1729        && FindProcShort (glProgramUniform2uiv)
1730        && FindProcShort (glProgramUniform3uiv)
1731        && FindProcShort (glProgramUniform4uiv)
1732        && FindProcShort (glProgramUniform1fv)
1733        && FindProcShort (glProgramUniform2fv)
1734        && FindProcShort (glProgramUniform3fv)
1735        && FindProcShort (glProgramUniform4fv)
1736        && FindProcShort (glProgramUniformMatrix2fv)
1737        && FindProcShort (glProgramUniformMatrix3fv)
1738        && FindProcShort (glProgramUniformMatrix4fv)
1739        && FindProcShort (glProgramUniformMatrix2x3fv)
1740        && FindProcShort (glProgramUniformMatrix3x2fv)
1741        && FindProcShort (glProgramUniformMatrix2x4fv)
1742        && FindProcShort (glProgramUniformMatrix4x2fv)
1743        && FindProcShort (glProgramUniformMatrix3x4fv)
1744        && FindProcShort (glProgramUniformMatrix4x3fv)
1745        && FindProcShort (glValidateProgramPipeline)
1746        && FindProcShort (glGetProgramPipelineInfoLog)
1747        && FindProcShort (glBindImageTexture)
1748        && FindProcShort (glGetBooleani_v)
1749        && FindProcShort (glMemoryBarrier)
1750        && FindProcShort (glMemoryBarrierByRegion)
1751        && FindProcShort (glTexStorage2DMultisample)
1752        && FindProcShort (glGetMultisamplefv)
1753        && FindProcShort (glSampleMaski)
1754        && FindProcShort (glGetTexLevelParameteriv)
1755        && FindProcShort (glGetTexLevelParameterfv)
1756        && FindProcShort (glBindVertexBuffer)
1757        && FindProcShort (glVertexAttribFormat)
1758        && FindProcShort (glVertexAttribIFormat)
1759        && FindProcShort (glVertexAttribBinding)
1760        && FindProcShort (glVertexBindingDivisor);
1761   if (!has31es)
1762   {
1763     checkWrongVersion (3, 1, aLastFailedProc);
1764   }
1765
1766   // initialize debug context extension
1767   if (IsGlGreaterEqual (3, 2)
1768    || CheckExtension ("GL_KHR_debug"))
1769   {
1770     // this functionality become a part of OpenGL ES 3.2
1771     arbDbg = NULL;
1772     if (IsGlGreaterEqual (3, 2)
1773      && FindProcShort (glDebugMessageControl)
1774      && FindProcShort (glDebugMessageInsert)
1775      && FindProcShort (glDebugMessageCallback)
1776      && FindProcShort (glGetDebugMessageLog))
1777     {
1778       arbDbg = (OpenGl_ArbDbg* )(&(*myFuncs));
1779     }
1780     // According to GL_KHR_debug spec, all functions should have KHR suffix.
1781     // However, some implementations can export these functions without suffix.
1782     else if (!IsGlGreaterEqual (3, 2)
1783      && FindProc ("glDebugMessageControlKHR",  myFuncs->glDebugMessageControl)
1784      && FindProc ("glDebugMessageInsertKHR",   myFuncs->glDebugMessageInsert)
1785      && FindProc ("glDebugMessageCallbackKHR", myFuncs->glDebugMessageCallback)
1786      && FindProc ("glGetDebugMessageLogKHR",   myFuncs->glGetDebugMessageLog))
1787     {
1788       arbDbg = (OpenGl_ArbDbg* )(&(*myFuncs));
1789     }
1790
1791     if (arbDbg != NULL
1792      && caps->contextDebug)
1793     {
1794       // setup default callback
1795       myIsGlDebugCtx = Standard_True;
1796       arbDbg->glDebugMessageCallback (debugCallbackWrap, this);
1797       ::glEnable (GL_DEBUG_OUTPUT);
1798       if (caps->contextSyncDebug)
1799       {
1800         // note that some broken implementations (e.g. simulators) might generate error message on this call
1801         ::glEnable (GL_DEBUG_OUTPUT_SYNCHRONOUS);
1802       }
1803     }
1804   }
1805
1806   // load OpenGL ES 3.2 new functions
1807   const bool has32es = IsGlGreaterEqual (3, 2)
1808        && has31es
1809        && hasTexBuffer32
1810        && arbDbg != NULL
1811        && FindProcShort (glBlendBarrier)
1812        && FindProcShort (glCopyImageSubData)
1813        && FindProcShort (glPushDebugGroup)
1814        && FindProcShort (glPopDebugGroup)
1815        && FindProcShort (glObjectLabel)
1816        && FindProcShort (glGetObjectLabel)
1817        && FindProcShort (glObjectPtrLabel)
1818        && FindProcShort (glGetObjectPtrLabel)
1819        && FindProcShort (glGetPointerv)
1820        && FindProcShort (glEnablei)
1821        && FindProcShort (glDisablei)
1822        && FindProcShort (glBlendEquationi)
1823        && FindProcShort (glBlendEquationSeparatei)
1824        && FindProcShort (glBlendFunci)
1825        && FindProcShort (glBlendFuncSeparatei)
1826        && FindProcShort (glColorMaski)
1827        && FindProcShort (glIsEnabledi)
1828        && FindProcShort (glDrawElementsBaseVertex)
1829        && FindProcShort (glDrawRangeElementsBaseVertex)
1830        && FindProcShort (glDrawElementsInstancedBaseVertex)
1831        && FindProcShort (glFramebufferTexture)
1832        && FindProcShort (glPrimitiveBoundingBox)
1833        && FindProcShort (glGetGraphicsResetStatus)
1834        && FindProcShort (glReadnPixels)
1835        && FindProcShort (glGetnUniformfv)
1836        && FindProcShort (glGetnUniformiv)
1837        && FindProcShort (glGetnUniformuiv)
1838        && FindProcShort (glMinSampleShading)
1839        && FindProcShort (glPatchParameteri)
1840        && FindProcShort (glTexParameterIiv)
1841        && FindProcShort (glTexParameterIuiv)
1842        && FindProcShort (glGetTexParameterIiv)
1843        && FindProcShort (glGetTexParameterIuiv)
1844        && FindProcShort (glSamplerParameterIiv)
1845        && FindProcShort (glSamplerParameterIuiv)
1846        && FindProcShort (glGetSamplerParameterIiv)
1847        && FindProcShort (glGetSamplerParameterIuiv)
1848        && FindProcShort (glTexBufferRange)
1849        && FindProcShort (glTexStorage3DMultisample);
1850   if (!has32es)
1851   {
1852     checkWrongVersion (3, 2, aLastFailedProc);
1853   }
1854
1855   extDrawBuffers = CheckExtension ("GL_EXT_draw_buffers") && FindProc ("glDrawBuffersEXT", myFuncs->glDrawBuffers);
1856   arbDrawBuffers = CheckExtension ("GL_ARB_draw_buffers") && FindProc ("glDrawBuffersARB", myFuncs->glDrawBuffers);
1857
1858   if (IsGlGreaterEqual (3, 0) && FindProcShort (glDrawBuffers))
1859   {
1860     hasDrawBuffers = OpenGl_FeatureInCore;
1861   }
1862   else if (extDrawBuffers || arbDrawBuffers)
1863   {
1864     hasDrawBuffers = OpenGl_FeatureInExtensions;
1865   }
1866
1867   hasFloatBuffer     = IsGlGreaterEqual (3, 2) ? OpenGl_FeatureInCore :
1868                        CheckExtension ("GL_EXT_color_buffer_float") ? OpenGl_FeatureInExtensions 
1869                                                                     : OpenGl_FeatureNotAvailable;
1870   hasHalfFloatBuffer = IsGlGreaterEqual (3, 2) ? OpenGl_FeatureInCore :
1871                        CheckExtension ("GL_EXT_color_buffer_half_float") ? OpenGl_FeatureInExtensions 
1872                                                                          : OpenGl_FeatureNotAvailable;
1873
1874   oesSampleVariables = CheckExtension ("GL_OES_sample_variables");
1875   oesStdDerivatives  = CheckExtension ("GL_OES_standard_derivatives");
1876   hasSampleVariables = IsGlGreaterEqual (3, 2) ? OpenGl_FeatureInCore :
1877                        oesSampleVariables ? OpenGl_FeatureInExtensions
1878                                           : OpenGl_FeatureNotAvailable;
1879   hasGlslBitwiseOps = IsGlGreaterEqual (3, 0)
1880                     ? OpenGl_FeatureInCore
1881                     : OpenGl_FeatureNotAvailable;
1882   // without hasHighp, dFdx/dFdy precision is considered too low for flat shading (visual artifacts)
1883   hasFlatShading = IsGlGreaterEqual (3, 0)
1884                  ? OpenGl_FeatureInCore
1885                   : (oesStdDerivatives && hasHighp
1886                    ? OpenGl_FeatureInExtensions
1887                    : OpenGl_FeatureNotAvailable);
1888   if (!IsGlGreaterEqual (3, 1)
1889     && myVendor.Search("qualcomm") != -1)
1890   {
1891     // dFdx/dFdy are completely broken on tested Adreno devices with versions below OpenGl ES 3.1
1892     hasFlatShading = OpenGl_FeatureNotAvailable;
1893   }
1894
1895   hasGeometryStage = IsGlGreaterEqual (3, 2)
1896                    ? OpenGl_FeatureInCore
1897                    : (CheckExtension ("GL_EXT_geometry_shader") && CheckExtension ("GL_EXT_shader_io_blocks")
1898                      ? OpenGl_FeatureInExtensions
1899                      : OpenGl_FeatureNotAvailable);
1900 #else
1901
1902   myTexClamp = IsGlGreaterEqual (1, 2) ? GL_CLAMP_TO_EDGE : GL_CLAMP;
1903
1904   hasTexRGBA8 = Standard_True;
1905   hasTexSRGB       = IsGlGreaterEqual (2, 1);
1906   hasFboSRGB       = IsGlGreaterEqual (2, 1);
1907   hasSRGBControl   = hasFboSRGB;
1908   arbDrawBuffers   = CheckExtension ("GL_ARB_draw_buffers");
1909   arbNPTW          = CheckExtension ("GL_ARB_texture_non_power_of_two");
1910   arbTexFloat      = IsGlGreaterEqual (3, 0)
1911                   || CheckExtension ("GL_ARB_texture_float");
1912   hasTexFloatLinear = arbTexFloat;
1913   arbSampleShading = CheckExtension ("GL_ARB_sample_shading");
1914   extBgra          = IsGlGreaterEqual (1, 2)
1915                   || CheckExtension ("GL_EXT_bgra");
1916   extAnis          = CheckExtension ("GL_EXT_texture_filter_anisotropic");
1917   extPDS           = CheckExtension ("GL_EXT_packed_depth_stencil");
1918   atiMem           = CheckExtension ("GL_ATI_meminfo");
1919   nvxMem           = CheckExtension ("GL_NVX_gpu_memory_info");
1920
1921   if (extBgra)
1922   {
1923     mySupportedFormats->Add (Image_PixMap::ImgBGR);
1924     mySupportedFormats->Add (Image_PixMap::ImgBGR32);
1925     mySupportedFormats->Add (Image_PixMap::ImgBGRA);
1926   }
1927
1928   hasDrawBuffers = IsGlGreaterEqual (2, 0) ? OpenGl_FeatureInCore :
1929                    arbDrawBuffers ? OpenGl_FeatureInExtensions 
1930                                   : OpenGl_FeatureNotAvailable;
1931
1932   hasGlslBitwiseOps = IsGlGreaterEqual (3, 0)
1933                     ? OpenGl_FeatureInCore
1934                     : CheckExtension ("GL_EXT_gpu_shader4")
1935                      ? OpenGl_FeatureInExtensions
1936                      : OpenGl_FeatureNotAvailable;
1937
1938   hasFloatBuffer = hasHalfFloatBuffer =  IsGlGreaterEqual (3, 0) ? OpenGl_FeatureInCore :
1939                                          CheckExtension ("GL_ARB_color_buffer_float") ? OpenGl_FeatureInExtensions
1940                                                                                       : OpenGl_FeatureNotAvailable;
1941
1942   hasGeometryStage = IsGlGreaterEqual (3, 2)
1943                    ? OpenGl_FeatureInCore
1944                    : OpenGl_FeatureNotAvailable;
1945
1946   hasSampleVariables = IsGlGreaterEqual (4, 0) ? OpenGl_FeatureInCore :
1947                         arbSampleShading ? OpenGl_FeatureInExtensions
1948                                          : OpenGl_FeatureNotAvailable;
1949
1950   GLint aStereo = GL_FALSE;
1951   glGetIntegerv (GL_STEREO, &aStereo);
1952   myIsStereoBuffers = aStereo == 1;
1953
1954   // get number of maximum clipping planes
1955   glGetIntegerv (GL_MAX_CLIP_PLANES,  &myMaxClipPlanes);
1956 #endif
1957
1958   if (hasDrawBuffers)
1959   {
1960     glGetIntegerv (GL_MAX_DRAW_BUFFERS,      &myMaxDrawBuffers);
1961     glGetIntegerv (GL_MAX_COLOR_ATTACHMENTS, &myMaxColorAttachments);
1962     if (myDrawBuffers.Length() < myMaxDrawBuffers)
1963     {
1964       myDrawBuffers.Resize (0, myMaxDrawBuffers - 1, false);
1965     }
1966   }
1967
1968   glGetIntegerv (GL_MAX_TEXTURE_SIZE, &myMaxTexDim);
1969 #if !defined(GL_ES_VERSION_2_0)
1970   if (IsGlGreaterEqual (1, 3) && core11 != NULL)
1971   {
1972     // this is a maximum of texture units for FFP functionality,
1973     // usually smaller than combined texture units available for GLSL
1974     glGetIntegerv (GL_MAX_TEXTURE_UNITS, &myMaxTexUnitsFFP);
1975     myMaxTexCombined = myMaxTexUnitsFFP;
1976   }
1977 #endif
1978   if (IsGlGreaterEqual (2, 0))
1979   {
1980     glGetIntegerv (GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &myMaxTexCombined);
1981   }
1982   mySpriteTexUnit = myMaxTexCombined >= 2
1983                   ? Graphic3d_TextureUnit_PointSprite
1984                   : Graphic3d_TextureUnit_0;
1985
1986   GLint aMaxVPortSize[2] = {0, 0};
1987   glGetIntegerv (GL_MAX_VIEWPORT_DIMS, aMaxVPortSize);
1988   myMaxDumpSizeX = Min (aMaxVPortSize[0], myMaxTexDim);
1989   myMaxDumpSizeY = Min (aMaxVPortSize[1], myMaxTexDim);
1990   if (myVendor == "intel")
1991   {
1992     // Intel drivers have known bug with empty dump for images with width>=5462
1993     myMaxDumpSizeX = Min (myMaxDumpSizeX, 4096);
1994   }
1995
1996   if (extAnis)
1997   {
1998     glGetIntegerv (GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &myAnisoMax);
1999   }
2000
2001   myClippingState.Init();
2002
2003 #if !defined(GL_ES_VERSION_2_0)
2004
2005   bool has12 = false;
2006   bool has13 = false;
2007   bool has14 = false;
2008   bool has15 = false;
2009   bool has20 = false;
2010   bool has21 = false;
2011   bool has30 = false;
2012   bool has31 = false;
2013   bool has32 = false;
2014   bool has33 = false;
2015   bool has40 = false;
2016   bool has41 = false;
2017   bool has42 = false;
2018   bool has43 = false;
2019   bool has44 = false;
2020   bool has45 = false;
2021
2022   // retrieve platform-dependent extensions
2023 #if defined(HAVE_EGL)
2024   //
2025 #elif defined(_WIN32)
2026   if (FindProcShort (wglGetExtensionsStringARB))
2027   {
2028     const char* aWglExts = myFuncs->wglGetExtensionsStringARB (wglGetCurrentDC());
2029     if (CheckExtension (aWglExts, "WGL_EXT_swap_control"))
2030     {
2031       FindProcShort (wglSwapIntervalEXT);
2032     }
2033     if (CheckExtension (aWglExts, "WGL_ARB_pixel_format"))
2034     {
2035       FindProcShort (wglChoosePixelFormatARB);
2036     }
2037     if (CheckExtension (aWglExts, "WGL_ARB_create_context_profile"))
2038     {
2039       FindProcShort (wglCreateContextAttribsARB);
2040     }
2041     if (CheckExtension (aWglExts, "WGL_NV_DX_interop"))
2042     {
2043       FindProcShort (wglDXSetResourceShareHandleNV);
2044       FindProcShort (wglDXOpenDeviceNV);
2045       FindProcShort (wglDXCloseDeviceNV);
2046       FindProcShort (wglDXRegisterObjectNV);
2047       FindProcShort (wglDXUnregisterObjectNV);
2048       FindProcShort (wglDXObjectAccessNV);
2049       FindProcShort (wglDXLockObjectsNV);
2050       FindProcShort (wglDXUnlockObjectsNV);
2051     }
2052     if (CheckExtension (aWglExts, "WGL_AMD_gpu_association"))
2053     {
2054       FindProcShort (wglGetGPUIDsAMD);
2055       FindProcShort (wglGetGPUInfoAMD);
2056       FindProcShort (wglGetContextGPUIDAMD);
2057     }
2058   }
2059 #elif defined(__APPLE__)
2060     //
2061 #else
2062     const char* aGlxExts = ::glXQueryExtensionsString ((Display* )myDisplay, DefaultScreen ((Display* )myDisplay));
2063     if (CheckExtension (aGlxExts, "GLX_EXT_swap_control"))
2064     {
2065       FindProcShort (glXSwapIntervalEXT);
2066     }
2067     if (CheckExtension (aGlxExts, "GLX_SGI_swap_control"))
2068     {
2069       FindProcShort (glXSwapIntervalSGI);
2070     }
2071     if (CheckExtension (aGlxExts, "GLX_MESA_query_renderer"))
2072     {
2073       FindProcShort (glXQueryRendererIntegerMESA);
2074       FindProcShort (glXQueryCurrentRendererIntegerMESA);
2075       FindProcShort (glXQueryRendererStringMESA);
2076       FindProcShort (glXQueryCurrentRendererStringMESA);
2077     }
2078     //extSwapTear = CheckExtension (aGlxExts, "GLX_EXT_swap_control_tear");
2079 #endif
2080
2081   // load OpenGL 1.2 new functions
2082   has12 = IsGlGreaterEqual (1, 2)
2083        && FindProcShort (glBlendColor)
2084        && FindProcShort (glBlendEquation)
2085        && FindProcShort (glDrawRangeElements)
2086        && FindProcShort (glTexImage3D)
2087        && FindProcShort (glTexSubImage3D)
2088        && FindProcShort (glCopyTexSubImage3D);
2089   if (!has12)
2090   {
2091     checkWrongVersion (1, 2, aLastFailedProc);
2092   }
2093
2094   // load OpenGL 1.3 new functions
2095   has13 = IsGlGreaterEqual (1, 3)
2096        && FindProcShort (glActiveTexture)
2097        && FindProcShort (glSampleCoverage)
2098        && FindProcShort (glCompressedTexImage3D)
2099        && FindProcShort (glCompressedTexImage2D)
2100        && FindProcShort (glCompressedTexImage1D)
2101        && FindProcShort (glCompressedTexSubImage3D)
2102        && FindProcShort (glCompressedTexSubImage2D)
2103        && FindProcShort (glCompressedTexSubImage1D)
2104        && FindProcShort (glGetCompressedTexImage);
2105
2106   if (!isCoreProfile)
2107   {
2108     has13 = has13
2109        && FindProcShort (glClientActiveTexture)
2110        && FindProcShort (glMultiTexCoord1d)
2111        && FindProcShort (glMultiTexCoord1dv)
2112        && FindProcShort (glMultiTexCoord1f)
2113        && FindProcShort (glMultiTexCoord1fv)
2114        && FindProcShort (glMultiTexCoord1i)
2115        && FindProcShort (glMultiTexCoord1iv)
2116        && FindProcShort (glMultiTexCoord1s)
2117        && FindProcShort (glMultiTexCoord1sv)
2118        && FindProcShort (glMultiTexCoord2d)
2119        && FindProcShort (glMultiTexCoord2dv)
2120        && FindProcShort (glMultiTexCoord2f)
2121        && FindProcShort (glMultiTexCoord2fv)
2122        && FindProcShort (glMultiTexCoord2i)
2123        && FindProcShort (glMultiTexCoord2iv)
2124        && FindProcShort (glMultiTexCoord2s)
2125        && FindProcShort (glMultiTexCoord2sv)
2126        && FindProcShort (glMultiTexCoord3d)
2127        && FindProcShort (glMultiTexCoord3dv)
2128        && FindProcShort (glMultiTexCoord3f)
2129        && FindProcShort (glMultiTexCoord3fv)
2130        && FindProcShort (glMultiTexCoord3i)
2131        && FindProcShort (glMultiTexCoord3iv)
2132        && FindProcShort (glMultiTexCoord3s)
2133        && FindProcShort (glMultiTexCoord3sv)
2134        && FindProcShort (glMultiTexCoord4d)
2135        && FindProcShort (glMultiTexCoord4dv)
2136        && FindProcShort (glMultiTexCoord4f)
2137        && FindProcShort (glMultiTexCoord4fv)
2138        && FindProcShort (glMultiTexCoord4i)
2139        && FindProcShort (glMultiTexCoord4iv)
2140        && FindProcShort (glMultiTexCoord4s)
2141        && FindProcShort (glMultiTexCoord4sv)
2142        && FindProcShort (glLoadTransposeMatrixf)
2143        && FindProcShort (glLoadTransposeMatrixd)
2144        && FindProcShort (glMultTransposeMatrixf)
2145        && FindProcShort (glMultTransposeMatrixd);
2146   }
2147   if (!has13)
2148   {
2149     checkWrongVersion (1, 3, aLastFailedProc);
2150   }
2151
2152   // load OpenGL 1.4 new functions
2153   has14 = IsGlGreaterEqual (1, 4)
2154        && FindProcShort (glBlendFuncSeparate)
2155        && FindProcShort (glMultiDrawArrays)
2156        && FindProcShort (glMultiDrawElements)
2157        && FindProcShort (glPointParameterf)
2158        && FindProcShort (glPointParameterfv)
2159        && FindProcShort (glPointParameteri)
2160        && FindProcShort (glPointParameteriv);
2161   if (!has14)
2162   {
2163     checkWrongVersion (1, 4, aLastFailedProc);
2164   }
2165
2166   // load OpenGL 1.5 new functions
2167   has15 = IsGlGreaterEqual (1, 5)
2168        && FindProcShort (glGenQueries)
2169        && FindProcShort (glDeleteQueries)
2170        && FindProcShort (glIsQuery)
2171        && FindProcShort (glBeginQuery)
2172        && FindProcShort (glEndQuery)
2173        && FindProcShort (glGetQueryiv)
2174        && FindProcShort (glGetQueryObjectiv)
2175        && FindProcShort (glGetQueryObjectuiv)
2176        && FindProcShort (glBindBuffer)
2177        && FindProcShort (glDeleteBuffers)
2178        && FindProcShort (glGenBuffers)
2179        && FindProcShort (glIsBuffer)
2180        && FindProcShort (glBufferData)
2181        && FindProcShort (glBufferSubData)
2182        && FindProcShort (glGetBufferSubData)
2183        && FindProcShort (glMapBuffer)
2184        && FindProcShort (glUnmapBuffer)
2185        && FindProcShort (glGetBufferParameteriv)
2186        && FindProcShort (glGetBufferPointerv);
2187   if (has15)
2188   {
2189     if (!isCoreProfile)
2190     {
2191       core15 = (OpenGl_GlCore15* )(&(*myFuncs));
2192     }
2193     core15fwd = (OpenGl_GlCore15Fwd* )(&(*myFuncs));
2194     hasGetBufferData = true;
2195   }
2196   else
2197   {
2198     checkWrongVersion (1, 5, aLastFailedProc);
2199   }
2200
2201   // load OpenGL 2.0 new functions
2202   has20 = IsGlGreaterEqual (2, 0)
2203        && FindProcShort (glBlendEquationSeparate)
2204        && FindProcShort (glDrawBuffers)
2205        && FindProcShort (glStencilOpSeparate)
2206        && FindProcShort (glStencilFuncSeparate)
2207        && FindProcShort (glStencilMaskSeparate)
2208        && FindProcShort (glAttachShader)
2209        && FindProcShort (glBindAttribLocation)
2210        && FindProcShort (glCompileShader)
2211        && FindProcShort (glCreateProgram)
2212        && FindProcShort (glCreateShader)
2213        && FindProcShort (glDeleteProgram)
2214        && FindProcShort (glDeleteShader)
2215        && FindProcShort (glDetachShader)
2216        && FindProcShort (glDisableVertexAttribArray)
2217        && FindProcShort (glEnableVertexAttribArray)
2218        && FindProcShort (glGetActiveAttrib)
2219        && FindProcShort (glGetActiveUniform)
2220        && FindProcShort (glGetAttachedShaders)
2221        && FindProcShort (glGetAttribLocation)
2222        && FindProcShort (glGetProgramiv)
2223        && FindProcShort (glGetProgramInfoLog)
2224        && FindProcShort (glGetShaderiv)
2225        && FindProcShort (glGetShaderInfoLog)
2226        && FindProcShort (glGetShaderSource)
2227        && FindProcShort (glGetUniformLocation)
2228        && FindProcShort (glGetUniformfv)
2229        && FindProcShort (glGetUniformiv)
2230        && FindProcShort (glGetVertexAttribdv)
2231        && FindProcShort (glGetVertexAttribfv)
2232        && FindProcShort (glGetVertexAttribiv)
2233        && FindProcShort (glGetVertexAttribPointerv)
2234        && FindProcShort (glIsProgram)
2235        && FindProcShort (glIsShader)
2236        && FindProcShort (glLinkProgram)
2237        && FindProcShort (glShaderSource)
2238        && FindProcShort (glUseProgram)
2239        && FindProcShort (glUniform1f)
2240        && FindProcShort (glUniform2f)
2241        && FindProcShort (glUniform3f)
2242        && FindProcShort (glUniform4f)
2243        && FindProcShort (glUniform1i)
2244        && FindProcShort (glUniform2i)
2245        && FindProcShort (glUniform3i)
2246        && FindProcShort (glUniform4i)
2247        && FindProcShort (glUniform1fv)
2248        && FindProcShort (glUniform2fv)
2249        && FindProcShort (glUniform3fv)
2250        && FindProcShort (glUniform4fv)
2251        && FindProcShort (glUniform1iv)
2252        && FindProcShort (glUniform2iv)
2253        && FindProcShort (glUniform3iv)
2254        && FindProcShort (glUniform4iv)
2255        && FindProcShort (glUniformMatrix2fv)
2256        && FindProcShort (glUniformMatrix3fv)
2257        && FindProcShort (glUniformMatrix4fv)
2258        && FindProcShort (glValidateProgram)
2259        && FindProcShort (glVertexAttrib1d)
2260        && FindProcShort (glVertexAttrib1dv)
2261        && FindProcShort (glVertexAttrib1f)
2262        && FindProcShort (glVertexAttrib1fv)
2263        && FindProcShort (glVertexAttrib1s)
2264        && FindProcShort (glVertexAttrib1sv)
2265        && FindProcShort (glVertexAttrib2d)
2266        && FindProcShort (glVertexAttrib2dv)
2267        && FindProcShort (glVertexAttrib2f)
2268        && FindProcShort (glVertexAttrib2fv)
2269        && FindProcShort (glVertexAttrib2s)
2270        && FindProcShort (glVertexAttrib2sv)
2271        && FindProcShort (glVertexAttrib3d)
2272        && FindProcShort (glVertexAttrib3dv)
2273        && FindProcShort (glVertexAttrib3f)
2274        && FindProcShort (glVertexAttrib3fv)
2275        && FindProcShort (glVertexAttrib3s)
2276        && FindProcShort (glVertexAttrib3sv)
2277        && FindProcShort (glVertexAttrib4Nbv)
2278        && FindProcShort (glVertexAttrib4Niv)
2279        && FindProcShort (glVertexAttrib4Nsv)
2280        && FindProcShort (glVertexAttrib4Nub)
2281        && FindProcShort (glVertexAttrib4Nubv)
2282        && FindProcShort (glVertexAttrib4Nuiv)
2283        && FindProcShort (glVertexAttrib4Nusv)
2284        && FindProcShort (glVertexAttrib4bv)
2285        && FindProcShort (glVertexAttrib4d)
2286        && FindProcShort (glVertexAttrib4dv)
2287        && FindProcShort (glVertexAttrib4f)
2288        && FindProcShort (glVertexAttrib4fv)
2289        && FindProcShort (glVertexAttrib4iv)
2290        && FindProcShort (glVertexAttrib4s)
2291        && FindProcShort (glVertexAttrib4sv)
2292        && FindProcShort (glVertexAttrib4ubv)
2293        && FindProcShort (glVertexAttrib4uiv)
2294        && FindProcShort (glVertexAttrib4usv)
2295        && FindProcShort (glVertexAttribPointer);
2296   if (has20)
2297   {
2298     const char* aGlslVer = (const char* )::glGetString (GL_SHADING_LANGUAGE_VERSION);
2299     if (aGlslVer == NULL
2300     || *aGlslVer == '\0')
2301     {
2302       // broken context has been detected
2303       PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
2304                    TCollection_AsciiString("Error! OpenGL context reports version ")
2305                    + myGlVerMajor  + "." + myGlVerMinor + " but reports wrong GLSL version");
2306       myGlVerMajor = 1;
2307       myGlVerMinor = 5;
2308     }
2309     else
2310     {
2311       if (!isCoreProfile)
2312       {
2313         core20  = (OpenGl_GlCore20*    )(&(*myFuncs));
2314       }
2315       core20fwd = (OpenGl_GlCore20Fwd* )(&(*myFuncs));
2316     }
2317   }
2318   else
2319   {
2320     checkWrongVersion (2, 0, aLastFailedProc);
2321   }
2322
2323   // load OpenGL 2.1 new functions
2324   has21 = IsGlGreaterEqual (2, 1)
2325        && FindProcShort (glUniformMatrix2x3fv)
2326        && FindProcShort (glUniformMatrix3x2fv)
2327        && FindProcShort (glUniformMatrix2x4fv)
2328        && FindProcShort (glUniformMatrix4x2fv)
2329        && FindProcShort (glUniformMatrix3x4fv)
2330        && FindProcShort (glUniformMatrix4x3fv);
2331   if (!has21)
2332   {
2333     checkWrongVersion (2, 1, aLastFailedProc);
2334   }
2335
2336   // load GL_ARB_framebuffer_object (added to OpenGL 3.0 core)
2337   const bool hasFBO = (IsGlGreaterEqual (3, 0) || CheckExtension ("GL_ARB_framebuffer_object"))
2338        && FindProcShort (glIsRenderbuffer)
2339        && FindProcShort (glBindRenderbuffer)
2340        && FindProcShort (glDeleteRenderbuffers)
2341        && FindProcShort (glGenRenderbuffers)
2342        && FindProcShort (glRenderbufferStorage)
2343        && FindProcShort (glGetRenderbufferParameteriv)
2344        && FindProcShort (glIsFramebuffer)
2345        && FindProcShort (glBindFramebuffer)
2346        && FindProcShort (glDeleteFramebuffers)
2347        && FindProcShort (glGenFramebuffers)
2348        && FindProcShort (glCheckFramebufferStatus)
2349        && FindProcShort (glFramebufferTexture1D)
2350        && FindProcShort (glFramebufferTexture2D)
2351        && FindProcShort (glFramebufferTexture3D)
2352        && FindProcShort (glFramebufferRenderbuffer)
2353        && FindProcShort (glGetFramebufferAttachmentParameteriv)
2354        && FindProcShort (glGenerateMipmap)
2355        && FindProcShort (glBlitFramebuffer)
2356        && FindProcShort (glRenderbufferStorageMultisample)
2357        && FindProcShort (glFramebufferTextureLayer);
2358
2359   // load GL_ARB_vertex_array_object (added to OpenGL 3.0 core)
2360   const bool hasVAO = (IsGlGreaterEqual (3, 0) || CheckExtension ("GL_ARB_vertex_array_object"))
2361        && FindProcShort (glBindVertexArray)
2362        && FindProcShort (glDeleteVertexArrays)
2363        && FindProcShort (glGenVertexArrays)
2364        && FindProcShort (glIsVertexArray);
2365
2366   // load GL_ARB_map_buffer_range (added to OpenGL 3.0 core)
2367   const bool hasMapBufferRange = (IsGlGreaterEqual (3, 0) || CheckExtension ("GL_ARB_map_buffer_range"))
2368        && FindProcShort (glMapBufferRange)
2369        && FindProcShort (glFlushMappedBufferRange);
2370
2371   // load OpenGL 3.0 new functions
2372   has30 = IsGlGreaterEqual (3, 0)
2373        && hasFBO
2374        && hasVAO
2375        && hasMapBufferRange
2376        && FindProcShort (glColorMaski)
2377        && FindProcShort (glGetBooleani_v)
2378        && FindProcShort (glGetIntegeri_v)
2379        && FindProcShort (glEnablei)
2380        && FindProcShort (glDisablei)
2381        && FindProcShort (glIsEnabledi)
2382        && FindProcShort (glBeginTransformFeedback)
2383        && FindProcShort (glEndTransformFeedback)
2384        && FindProcShort (glBindBufferRange)
2385        && FindProcShort (glBindBufferBase)
2386        && FindProcShort (glTransformFeedbackVaryings)
2387        && FindProcShort (glGetTransformFeedbackVarying)
2388        && FindProcShort (glClampColor)
2389        && FindProcShort (glBeginConditionalRender)
2390        && FindProcShort (glEndConditionalRender)
2391        && FindProcShort (glVertexAttribIPointer)
2392        && FindProcShort (glGetVertexAttribIiv)
2393        && FindProcShort (glGetVertexAttribIuiv)
2394        && FindProcShort (glVertexAttribI1i)
2395        && FindProcShort (glVertexAttribI2i)
2396        && FindProcShort (glVertexAttribI3i)
2397        && FindProcShort (glVertexAttribI4i)
2398        && FindProcShort (glVertexAttribI1ui)
2399        && FindProcShort (glVertexAttribI2ui)
2400        && FindProcShort (glVertexAttribI3ui)
2401        && FindProcShort (glVertexAttribI4ui)
2402        && FindProcShort (glVertexAttribI1iv)
2403        && FindProcShort (glVertexAttribI2iv)
2404        && FindProcShort (glVertexAttribI3iv)
2405        && FindProcShort (glVertexAttribI4iv)
2406        && FindProcShort (glVertexAttribI1uiv)
2407        && FindProcShort (glVertexAttribI2uiv)
2408        && FindProcShort (glVertexAttribI3uiv)
2409        && FindProcShort (glVertexAttribI4uiv)
2410        && FindProcShort (glVertexAttribI4bv)
2411        && FindProcShort (glVertexAttribI4sv)
2412        && FindProcShort (glVertexAttribI4ubv)
2413        && FindProcShort (glVertexAttribI4usv)
2414        && FindProcShort (glGetUniformuiv)
2415        && FindProcShort (glBindFragDataLocation)
2416        && FindProcShort (glGetFragDataLocation)
2417        && FindProcShort (glUniform1ui)
2418        && FindProcShort (glUniform2ui)
2419        && FindProcShort (glUniform3ui)
2420        && FindProcShort (glUniform4ui)
2421        && FindProcShort (glUniform1uiv)
2422        && FindProcShort (glUniform2uiv)
2423        && FindProcShort (glUniform3uiv)
2424        && FindProcShort (glUniform4uiv)
2425        && FindProcShort (glTexParameterIiv)
2426        && FindProcShort (glTexParameterIuiv)
2427        && FindProcShort (glGetTexParameterIiv)
2428        && FindProcShort (glGetTexParameterIuiv)
2429        && FindProcShort (glClearBufferiv)
2430        && FindProcShort (glClearBufferuiv)
2431        && FindProcShort (glClearBufferfv)
2432        && FindProcShort (glClearBufferfi)
2433        && FindProcShort (glGetStringi);
2434   if (!has30)
2435   {
2436     checkWrongVersion (3, 0, aLastFailedProc);
2437   }
2438
2439   // load GL_ARB_uniform_buffer_object (added to OpenGL 3.1 core)
2440   const bool hasUBO = (IsGlGreaterEqual (3, 1) || CheckExtension ("GL_ARB_uniform_buffer_object"))
2441        && FindProcShort (glGetUniformIndices)
2442        && FindProcShort (glGetActiveUniformsiv)
2443        && FindProcShort (glGetActiveUniformName)
2444        && FindProcShort (glGetUniformBlockIndex)
2445        && FindProcShort (glGetActiveUniformBlockiv)
2446        && FindProcShort (glGetActiveUniformBlockName)
2447        && FindProcShort (glUniformBlockBinding);
2448
2449   // load GL_ARB_copy_buffer (added to OpenGL 3.1 core)
2450   const bool hasCopyBufSubData = (IsGlGreaterEqual (3, 1) || CheckExtension ("GL_ARB_copy_buffer"))
2451        && FindProcShort (glCopyBufferSubData);
2452
2453   if (has30)
2454   {
2455     // NPOT textures are required by OpenGL 2.0 specifications
2456     // but doesn't hardware accelerated by some ancient OpenGL 2.1 hardware (GeForce FX, RadeOn 9700 etc.)
2457     arbNPTW  = Standard_True;
2458     arbTexRG = Standard_True;
2459
2460     if (!isCoreProfile)
2461     {
2462       core30 = (OpenGl_GlCore30* )(&(*myFuncs));
2463     }
2464     core30fwd = (OpenGl_GlCore30Fwd* )(&(*myFuncs));
2465   }
2466
2467   // load OpenGL 3.1 new functions
2468   has31 = IsGlGreaterEqual (3, 1)
2469        && hasUBO
2470        && hasCopyBufSubData
2471        && FindProcShort (glDrawArraysInstanced)
2472        && FindProcShort (glDrawElementsInstanced)
2473        && FindProcShort (glTexBuffer)
2474        && FindProcShort (glPrimitiveRestartIndex);
2475   if (has31)
2476   {
2477     arbTBO = (OpenGl_ArbTBO* )(&(*myFuncs));
2478     arbIns = (OpenGl_ArbIns* )(&(*myFuncs));
2479   }
2480   else
2481   {
2482     checkWrongVersion (3, 1, aLastFailedProc);
2483
2484     // initialize TBO extension (ARB)
2485     if (CheckExtension ("GL_ARB_texture_buffer_object")
2486      && FindProc ("glTexBufferARB", myFuncs->glTexBuffer))
2487     {
2488       arbTBO = (OpenGl_ArbTBO* )(&(*myFuncs));
2489     }
2490
2491     // initialize hardware instancing extension (ARB)
2492     if (CheckExtension ("GL_ARB_draw_instanced")
2493      && FindProc ("glDrawArraysInstancedARB",   myFuncs->glDrawArraysInstanced)
2494      && FindProc ("glDrawElementsInstancedARB", myFuncs->glDrawElementsInstanced))
2495     {
2496       arbIns = (OpenGl_ArbIns* )(&(*myFuncs));
2497     }
2498   }
2499
2500   arbTboRGB32 = CheckExtension ("GL_ARB_texture_buffer_object_rgb32");
2501
2502   // load GL_ARB_draw_elements_base_vertex (added to OpenGL 3.2 core)
2503   const bool hasDrawElemsBaseVert = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_draw_elements_base_vertex"))
2504        && FindProcShort (glDrawElementsBaseVertex)
2505        && FindProcShort (glDrawRangeElementsBaseVertex)
2506        && FindProcShort (glDrawElementsInstancedBaseVertex)
2507        && FindProcShort (glMultiDrawElementsBaseVertex);
2508
2509   // load GL_ARB_provoking_vertex (added to OpenGL 3.2 core)
2510   const bool hasProvokingVert = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_provoking_vertex"))
2511        && FindProcShort (glProvokingVertex);
2512
2513   // load GL_ARB_sync (added to OpenGL 3.2 core)
2514   const bool hasSync = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_sync"))
2515        && FindProcShort (glFenceSync)
2516        && FindProcShort (glIsSync)
2517        && FindProcShort (glDeleteSync)
2518        && FindProcShort (glClientWaitSync)
2519        && FindProcShort (glWaitSync)
2520        && FindProcShort (glGetInteger64v)
2521        && FindProcShort (glGetSynciv);
2522
2523   // load GL_ARB_texture_multisample (added to OpenGL 3.2 core)
2524   const bool hasTextureMultisample = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_texture_multisample"))
2525        && FindProcShort (glTexImage2DMultisample)
2526        && FindProcShort (glTexImage3DMultisample)
2527        && FindProcShort (glGetMultisamplefv)
2528        && FindProcShort (glSampleMaski);
2529
2530   // load OpenGL 3.2 new functions
2531   has32 = IsGlGreaterEqual (3, 2)
2532        && hasDrawElemsBaseVert
2533        && hasProvokingVert
2534        && hasSync
2535        && hasTextureMultisample
2536        && FindProcShort (glGetInteger64i_v)
2537        && FindProcShort (glGetBufferParameteri64v)
2538        && FindProcShort (glFramebufferTexture);
2539   if (has32)
2540   {
2541     core32 = (OpenGl_GlCore32* )(&(*myFuncs));
2542     if (isCoreProfile)
2543     {
2544       core32->glGenVertexArrays (1, &myDefaultVao);
2545     }
2546     else
2547     {
2548       core32back = (OpenGl_GlCore32Back* )(&(*myFuncs));
2549     }
2550     ::glGetIntegerv (GL_MAX_SAMPLES, &myMaxMsaaSamples);
2551   }
2552   else
2553   {
2554     checkWrongVersion (3, 2, aLastFailedProc);
2555   }
2556
2557   // load GL_ARB_blend_func_extended (added to OpenGL 3.3 core)
2558   const bool hasBlendFuncExtended = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_blend_func_extended"))
2559        && FindProcShort (glBindFragDataLocationIndexed)
2560        && FindProcShort (glGetFragDataIndex);
2561
2562   // load GL_ARB_sampler_objects (added to OpenGL 3.3 core)
2563   const bool hasSamplerObjects = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_sampler_objects"))
2564        && FindProcShort (glGenSamplers)
2565        && FindProcShort (glDeleteSamplers)
2566        && FindProcShort (glIsSampler)
2567        && FindProcShort (glBindSampler)
2568        && FindProcShort (glSamplerParameteri)
2569        && FindProcShort (glSamplerParameteriv)
2570        && FindProcShort (glSamplerParameterf)
2571        && FindProcShort (glSamplerParameterfv)
2572        && FindProcShort (glSamplerParameterIiv)
2573        && FindProcShort (glSamplerParameterIuiv)
2574        && FindProcShort (glGetSamplerParameteriv)
2575        && FindProcShort (glGetSamplerParameterIiv)
2576        && FindProcShort (glGetSamplerParameterfv)
2577        && FindProcShort (glGetSamplerParameterIuiv);
2578   if (hasSamplerObjects)
2579   {
2580     arbSamplerObject = (OpenGl_ArbSamplerObject* )(&(*myFuncs));
2581   }
2582
2583   // load GL_ARB_timer_query (added to OpenGL 3.3 core)
2584   const bool hasTimerQuery = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_timer_query"))
2585        && FindProcShort (glQueryCounter)
2586        && FindProcShort (glGetQueryObjecti64v)
2587        && FindProcShort (glGetQueryObjectui64v);
2588
2589   // load GL_ARB_vertex_type_2_10_10_10_rev (added to OpenGL 3.3 core)
2590   const bool hasVertType21010101rev = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_vertex_type_2_10_10_10_rev"))
2591        && FindProcShort (glVertexAttribP1ui)
2592        && FindProcShort (glVertexAttribP1uiv)
2593        && FindProcShort (glVertexAttribP2ui)
2594        && FindProcShort (glVertexAttribP2uiv)
2595        && FindProcShort (glVertexAttribP3ui)
2596        && FindProcShort (glVertexAttribP3uiv)
2597        && FindProcShort (glVertexAttribP4ui)
2598        && FindProcShort (glVertexAttribP4uiv);
2599
2600   if ( hasVertType21010101rev
2601    && !isCoreProfile)
2602   {
2603     // load deprecated functions
2604     const bool hasVertType21010101revExt =
2605           FindProcShort (glVertexP2ui)
2606        && FindProcShort (glVertexP2uiv)
2607        && FindProcShort (glVertexP3ui)
2608        && FindProcShort (glVertexP3uiv)
2609        && FindProcShort (glVertexP4ui)
2610        && FindProcShort (glVertexP4uiv)
2611        && FindProcShort (glTexCoordP1ui)
2612        && FindProcShort (glTexCoordP1uiv)
2613        && FindProcShort (glTexCoordP2ui)
2614        && FindProcShort (glTexCoordP2uiv)
2615        && FindProcShort (glTexCoordP3ui)
2616        && FindProcShort (glTexCoordP3uiv)
2617        && FindProcShort (glTexCoordP4ui)
2618        && FindProcShort (glTexCoordP4uiv)
2619        && FindProcShort (glMultiTexCoordP1ui)
2620        && FindProcShort (glMultiTexCoordP1uiv)
2621        && FindProcShort (glMultiTexCoordP2ui)
2622        && FindProcShort (glMultiTexCoordP2uiv)
2623        && FindProcShort (glMultiTexCoordP3ui)
2624        && FindProcShort (glMultiTexCoordP3uiv)
2625        && FindProcShort (glMultiTexCoordP4ui)
2626        && FindProcShort (glMultiTexCoordP4uiv)
2627        && FindProcShort (glNormalP3ui)
2628        && FindProcShort (glNormalP3uiv)
2629        && FindProcShort (glColorP3ui)
2630        && FindProcShort (glColorP3uiv)
2631        && FindProcShort (glColorP4ui)
2632        && FindProcShort (glColorP4uiv)
2633        && FindProcShort (glSecondaryColorP3ui)
2634        && FindProcShort (glSecondaryColorP3uiv);
2635     (void )hasVertType21010101revExt;
2636   }
2637
2638   // load OpenGL 3.3 extra functions
2639   has33 = IsGlGreaterEqual (3, 3)
2640        && hasBlendFuncExtended
2641        && hasSamplerObjects
2642        && hasTimerQuery
2643        && hasVertType21010101rev
2644        && FindProcShort (glVertexAttribDivisor);
2645   if (has33)
2646   {
2647     core33 = (OpenGl_GlCore33* )(&(*myFuncs));
2648     if (!isCoreProfile)
2649     {
2650       core33back = (OpenGl_GlCore33Back* )(&(*myFuncs));
2651     }
2652   }
2653   else
2654   {
2655     checkWrongVersion (3, 3, aLastFailedProc);
2656   }
2657
2658   // load GL_ARB_draw_indirect (added to OpenGL 4.0 core)
2659   const bool hasDrawIndirect = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_draw_indirect"))
2660        && FindProcShort (glDrawArraysIndirect)
2661        && FindProcShort (glDrawElementsIndirect);
2662
2663   // load GL_ARB_gpu_shader_fp64 (added to OpenGL 4.0 core)
2664   const bool hasShaderFP64 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_gpu_shader_fp64"))
2665        && FindProcShort (glUniform1d)
2666        && FindProcShort (glUniform2d)
2667        && FindProcShort (glUniform3d)
2668        && FindProcShort (glUniform4d)
2669        && FindProcShort (glUniform1dv)
2670        && FindProcShort (glUniform2dv)
2671        && FindProcShort (glUniform3dv)
2672        && FindProcShort (glUniform4dv)
2673        && FindProcShort (glUniformMatrix2dv)
2674        && FindProcShort (glUniformMatrix3dv)
2675        && FindProcShort (glUniformMatrix4dv)
2676        && FindProcShort (glUniformMatrix2x3dv)
2677        && FindProcShort (glUniformMatrix2x4dv)
2678        && FindProcShort (glUniformMatrix3x2dv)
2679        && FindProcShort (glUniformMatrix3x4dv)
2680        && FindProcShort (glUniformMatrix4x2dv)
2681        && FindProcShort (glUniformMatrix4x3dv)
2682        && FindProcShort (glGetUniformdv);
2683
2684   // load GL_ARB_shader_subroutine (added to OpenGL 4.0 core)
2685   const bool hasShaderSubroutine = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_shader_subroutine"))
2686        && FindProcShort (glGetSubroutineUniformLocation)
2687        && FindProcShort (glGetSubroutineIndex)
2688        && FindProcShort (glGetActiveSubroutineUniformiv)
2689        && FindProcShort (glGetActiveSubroutineUniformName)
2690        && FindProcShort (glGetActiveSubroutineName)
2691        && FindProcShort (glUniformSubroutinesuiv)
2692        && FindProcShort (glGetUniformSubroutineuiv)
2693        && FindProcShort (glGetProgramStageiv);
2694
2695   // load GL_ARB_tessellation_shader (added to OpenGL 4.0 core)
2696   const bool hasTessellationShader = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_tessellation_shader"))
2697        && FindProcShort (glPatchParameteri)
2698        && FindProcShort (glPatchParameterfv);
2699
2700   // load GL_ARB_transform_feedback2 (added to OpenGL 4.0 core)
2701   const bool hasTrsfFeedback2 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_transform_feedback2"))
2702        && FindProcShort (glBindTransformFeedback)
2703        && FindProcShort (glDeleteTransformFeedbacks)
2704        && FindProcShort (glGenTransformFeedbacks)
2705        && FindProcShort (glIsTransformFeedback)
2706        && FindProcShort (glPauseTransformFeedback)
2707        && FindProcShort (glResumeTransformFeedback)
2708        && FindProcShort (glDrawTransformFeedback);
2709
2710   // load GL_ARB_transform_feedback3 (added to OpenGL 4.0 core)
2711   const bool hasTrsfFeedback3 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_transform_feedback3"))
2712        && FindProcShort (glDrawTransformFeedbackStream)
2713        && FindProcShort (glBeginQueryIndexed)
2714        && FindProcShort (glEndQueryIndexed)
2715        && FindProcShort (glGetQueryIndexediv);
2716
2717   // load OpenGL 4.0 new functions
2718   has40 = IsGlGreaterEqual (4, 0)
2719       && hasDrawIndirect
2720       && hasShaderFP64
2721       && hasShaderSubroutine
2722       && hasTessellationShader
2723       && hasTrsfFeedback2
2724       && hasTrsfFeedback3
2725       && FindProcShort (glMinSampleShading)
2726       && FindProcShort (glBlendEquationi)
2727       && FindProcShort (glBlendEquationSeparatei)
2728       && FindProcShort (glBlendFunci)
2729       && FindProcShort (glBlendFuncSeparatei);
2730   if (has40)
2731   {
2732     arbTboRGB32 = Standard_True; // in core since OpenGL 4.0
2733   }
2734   else
2735   {
2736     checkWrongVersion (4, 0, aLastFailedProc);
2737   }
2738
2739   // load GL_ARB_ES2_compatibility (added to OpenGL 4.1 core)
2740   const bool hasES2Compatibility = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_ES2_compatibility"))
2741        && FindProcShort (glReleaseShaderCompiler)
2742        && FindProcShort (glShaderBinary)
2743        && FindProcShort (glGetShaderPrecisionFormat)
2744        && FindProcShort (glDepthRangef)
2745        && FindProcShort (glClearDepthf);
2746
2747   // load GL_ARB_get_program_binary (added to OpenGL 4.1 core)
2748   const bool hasGetProgramBinary = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_get_program_binary"))
2749        && FindProcShort (glGetProgramBinary)
2750        && FindProcShort (glProgramBinary)
2751        && FindProcShort (glProgramParameteri);
2752
2753
2754   // load GL_ARB_separate_shader_objects (added to OpenGL 4.1 core)
2755   const bool hasSeparateShaderObjects = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_separate_shader_objects"))
2756        && FindProcShort (glUseProgramStages)
2757        && FindProcShort (glActiveShaderProgram)
2758        && FindProcShort (glCreateShaderProgramv)
2759        && FindProcShort (glBindProgramPipeline)
2760        && FindProcShort (glDeleteProgramPipelines)
2761        && FindProcShort (glGenProgramPipelines)
2762        && FindProcShort (glIsProgramPipeline)
2763        && FindProcShort (glGetProgramPipelineiv)
2764        && FindProcShort (glProgramUniform1i)
2765        && FindProcShort (glProgramUniform1iv)
2766        && FindProcShort (glProgramUniform1f)
2767        && FindProcShort (glProgramUniform1fv)
2768        && FindProcShort (glProgramUniform1d)
2769        && FindProcShort (glProgramUniform1dv)
2770        && FindProcShort (glProgramUniform1ui)
2771        && FindProcShort (glProgramUniform1uiv)
2772        && FindProcShort (glProgramUniform2i)
2773        && FindProcShort (glProgramUniform2iv)
2774        && FindProcShort (glProgramUniform2f)
2775        && FindProcShort (glProgramUniform2fv)
2776        && FindProcShort (glProgramUniform2d)
2777        && FindProcShort (glProgramUniform2dv)
2778        && FindProcShort (glProgramUniform2ui)
2779        && FindProcShort (glProgramUniform2uiv)
2780        && FindProcShort (glProgramUniform3i)
2781        && FindProcShort (glProgramUniform3iv)
2782        && FindProcShort (glProgramUniform3f)
2783        && FindProcShort (glProgramUniform3fv)
2784        && FindProcShort (glProgramUniform3d)
2785        && FindProcShort (glProgramUniform3dv)
2786        && FindProcShort (glProgramUniform3ui)
2787        && FindProcShort (glProgramUniform3uiv)
2788        && FindProcShort (glProgramUniform4i)
2789        && FindProcShort (glProgramUniform4iv)
2790        && FindProcShort (glProgramUniform4f)
2791        && FindProcShort (glProgramUniform4fv)
2792        && FindProcShort (glProgramUniform4d)
2793        && FindProcShort (glProgramUniform4dv)
2794        && FindProcShort (glProgramUniform4ui)
2795        && FindProcShort (glProgramUniform4uiv)
2796        && FindProcShort (glProgramUniformMatrix2fv)
2797        && FindProcShort (glProgramUniformMatrix3fv)
2798        && FindProcShort (glProgramUniformMatrix4fv)
2799        && FindProcShort (glProgramUniformMatrix2dv)
2800        && FindProcShort (glProgramUniformMatrix3dv)
2801        && FindProcShort (glProgramUniformMatrix4dv)
2802        && FindProcShort (glProgramUniformMatrix2x3fv)
2803        && FindProcShort (glProgramUniformMatrix3x2fv)
2804        && FindProcShort (glProgramUniformMatrix2x4fv)
2805        && FindProcShort (glProgramUniformMatrix4x2fv)
2806        && FindProcShort (glProgramUniformMatrix3x4fv)
2807        && FindProcShort (glProgramUniformMatrix4x3fv)
2808        && FindProcShort (glProgramUniformMatrix2x3dv)
2809        && FindProcShort (glProgramUniformMatrix3x2dv)
2810        && FindProcShort (glProgramUniformMatrix2x4dv)
2811        && FindProcShort (glProgramUniformMatrix4x2dv)
2812        && FindProcShort (glProgramUniformMatrix3x4dv)
2813        && FindProcShort (glProgramUniformMatrix4x3dv)
2814        && FindProcShort (glValidateProgramPipeline)
2815        && FindProcShort (glGetProgramPipelineInfoLog);
2816
2817   // load GL_ARB_vertex_attrib_64bit (added to OpenGL 4.1 core)
2818   const bool hasVertAttrib64bit = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_vertex_attrib_64bit"))
2819        && FindProcShort (glVertexAttribL1d)
2820        && FindProcShort (glVertexAttribL2d)
2821        && FindProcShort (glVertexAttribL3d)
2822        && FindProcShort (glVertexAttribL4d)
2823        && FindProcShort (glVertexAttribL1dv)
2824        && FindProcShort (glVertexAttribL2dv)
2825        && FindProcShort (glVertexAttribL3dv)
2826        && FindProcShort (glVertexAttribL4dv)
2827        && FindProcShort (glVertexAttribLPointer)
2828        && FindProcShort (glGetVertexAttribLdv);
2829
2830   // load GL_ARB_viewport_array (added to OpenGL 4.1 core)
2831   const bool hasViewportArray = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_viewport_array"))
2832        && FindProcShort (glViewportArrayv)
2833        && FindProcShort (glViewportIndexedf)
2834        && FindProcShort (glViewportIndexedfv)
2835        && FindProcShort (glScissorArrayv)
2836        && FindProcShort (glScissorIndexed)
2837        && FindProcShort (glScissorIndexedv)
2838        && FindProcShort (glDepthRangeArrayv)
2839        && FindProcShort (glDepthRangeIndexed)
2840        && FindProcShort (glGetFloati_v)
2841        && FindProcShort (glGetDoublei_v);
2842
2843   has41 = IsGlGreaterEqual (4, 1)
2844        && hasES2Compatibility
2845        && hasGetProgramBinary
2846        && hasSeparateShaderObjects
2847        && hasVertAttrib64bit
2848        && hasViewportArray;
2849   if (has41)
2850   {
2851     core41 = (OpenGl_GlCore41* )(&(*myFuncs));
2852     if (!isCoreProfile)
2853     {
2854       core41back = (OpenGl_GlCore41Back* )(&(*myFuncs));
2855     }
2856   }
2857   else
2858   {
2859     checkWrongVersion (4, 1, aLastFailedProc);
2860   }
2861
2862   // load GL_ARB_base_instance (added to OpenGL 4.2 core)
2863   const bool hasBaseInstance = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_base_instance"))
2864        && FindProcShort (glDrawArraysInstancedBaseInstance)
2865        && FindProcShort (glDrawElementsInstancedBaseInstance)
2866        && FindProcShort (glDrawElementsInstancedBaseVertexBaseInstance);
2867
2868   // load GL_ARB_transform_feedback_instanced (added to OpenGL 4.2 core)
2869   const bool hasTrsfFeedbackInstanced = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_transform_feedback_instanced"))
2870        && FindProcShort (glDrawTransformFeedbackInstanced)
2871        && FindProcShort (glDrawTransformFeedbackStreamInstanced);
2872
2873   // load GL_ARB_internalformat_query (added to OpenGL 4.2 core)
2874   const bool hasInternalFormatQuery = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_internalformat_query"))
2875        && FindProcShort (glGetInternalformativ);
2876
2877   // load GL_ARB_shader_atomic_counters (added to OpenGL 4.2 core)
2878   const bool hasShaderAtomicCounters = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_shader_atomic_counters"))
2879        && FindProcShort (glGetActiveAtomicCounterBufferiv);
2880
2881   // load GL_ARB_shader_image_load_store (added to OpenGL 4.2 core)
2882   const bool hasShaderImgLoadStore = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_shader_image_load_store"))
2883        && FindProcShort (glBindImageTexture)
2884        && FindProcShort (glMemoryBarrier);
2885
2886   // load GL_ARB_texture_storage (added to OpenGL 4.2 core)
2887   const bool hasTextureStorage = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_texture_storage"))
2888        && FindProcShort (glTexStorage1D)
2889        && FindProcShort (glTexStorage2D)
2890        && FindProcShort (glTexStorage3D);
2891
2892   has42 = IsGlGreaterEqual (4, 2)
2893        && hasBaseInstance
2894        && hasTrsfFeedbackInstanced
2895        && hasInternalFormatQuery
2896        && hasShaderAtomicCounters
2897        && hasShaderImgLoadStore
2898        && hasTextureStorage;
2899   if (has42)
2900   {
2901     core42 = (OpenGl_GlCore42* )(&(*myFuncs));
2902     if (!isCoreProfile)
2903     {
2904       core42back = (OpenGl_GlCore42Back* )(&(*myFuncs));
2905     }
2906   }
2907   else
2908   {
2909     checkWrongVersion (4, 2, aLastFailedProc);
2910   }
2911
2912   has43 = IsGlGreaterEqual (4, 3)
2913        && FindProcShort (glClearBufferData)
2914        && FindProcShort (glClearBufferSubData)
2915        && FindProcShort (glDispatchCompute)
2916        && FindProcShort (glDispatchComputeIndirect)
2917        && FindProcShort (glCopyImageSubData)
2918        && FindProcShort (glFramebufferParameteri)
2919        && FindProcShort (glGetFramebufferParameteriv)
2920        && FindProcShort (glGetInternalformati64v)
2921        && FindProcShort (glInvalidateTexSubImage)
2922        && FindProcShort (glInvalidateTexImage)
2923        && FindProcShort (glInvalidateBufferSubData)
2924        && FindProcShort (glInvalidateBufferData)
2925        && FindProcShort (glInvalidateFramebuffer)
2926        && FindProcShort (glInvalidateSubFramebuffer)
2927        && FindProcShort (glMultiDrawArraysIndirect)
2928        && FindProcShort (glMultiDrawElementsIndirect)
2929        && FindProcShort (glGetProgramInterfaceiv)
2930        && FindProcShort (glGetProgramResourceIndex)
2931        && FindProcShort (glGetProgramResourceName)
2932        && FindProcShort (glGetProgramResourceiv)
2933        && FindProcShort (glGetProgramResourceLocation)
2934        && FindProcShort (glGetProgramResourceLocationIndex)
2935        && FindProcShort (glShaderStorageBlockBinding)
2936        && FindProcShort (glTexBufferRange)
2937        && FindProcShort (glTexStorage2DMultisample)
2938        && FindProcShort (glTexStorage3DMultisample)
2939        && FindProcShort (glTextureView)
2940        && FindProcShort (glBindVertexBuffer)
2941        && FindProcShort (glVertexAttribFormat)
2942        && FindProcShort (glVertexAttribIFormat)
2943        && FindProcShort (glVertexAttribLFormat)
2944        && FindProcShort (glVertexAttribBinding)
2945        && FindProcShort (glVertexBindingDivisor)
2946        && FindProcShort (glDebugMessageControl)
2947        && FindProcShort (glDebugMessageInsert)
2948        && FindProcShort (glDebugMessageCallback)
2949        && FindProcShort (glGetDebugMessageLog)
2950        && FindProcShort (glPushDebugGroup)
2951        && FindProcShort (glPopDebugGroup)
2952        && FindProcShort (glObjectLabel)
2953        && FindProcShort (glGetObjectLabel)
2954        && FindProcShort (glObjectPtrLabel)
2955        && FindProcShort (glGetObjectPtrLabel);
2956   if (has43)
2957   {
2958     core43 = (OpenGl_GlCore43* )(&(*myFuncs));
2959     if (!isCoreProfile)
2960     {
2961       core43back = (OpenGl_GlCore43Back* )(&(*myFuncs));
2962     }
2963   }
2964   else
2965   {
2966     checkWrongVersion (4, 3, aLastFailedProc);
2967   }
2968
2969   // load GL_ARB_clear_texture (added to OpenGL 4.4 core)
2970   bool arbTexClear = (IsGlGreaterEqual (4, 4) || CheckExtension ("GL_ARB_clear_texture"))
2971        && FindProcShort (glClearTexImage)
2972        && FindProcShort (glClearTexSubImage);
2973
2974   has44 = IsGlGreaterEqual (4, 4)
2975        && arbTexClear
2976        && FindProcShort (glBufferStorage)
2977        && FindProcShort (glBindBuffersBase)
2978        && FindProcShort (glBindBuffersRange)
2979        && FindProcShort (glBindTextures)
2980        && FindProcShort (glBindSamplers)
2981        && FindProcShort (glBindImageTextures)
2982        && FindProcShort (glBindVertexBuffers);
2983   if (has44)
2984   {
2985     core44 = (OpenGl_GlCore44* )(&(*myFuncs));
2986     if (!isCoreProfile)
2987     {
2988       core44back = (OpenGl_GlCore44Back* )(&(*myFuncs));
2989     }
2990   }
2991   else
2992   {
2993     checkWrongVersion (4, 4, aLastFailedProc);
2994   }
2995
2996   has45 = IsGlGreaterEqual (4, 5)
2997        && FindProcShort (glBindVertexBuffers)
2998        && FindProcShort (glClipControl)
2999        && FindProcShort (glCreateTransformFeedbacks)
3000        && FindProcShort (glTransformFeedbackBufferBase)
3001        && FindProcShort (glTransformFeedbackBufferRange)
3002        && FindProcShort (glGetTransformFeedbackiv)
3003        && FindProcShort (glGetTransformFeedbacki_v)
3004        && FindProcShort (glGetTransformFeedbacki64_v)
3005        && FindProcShort (glCreateBuffers)
3006        && FindProcShort (glNamedBufferStorage)
3007        && FindProcShort (glNamedBufferData)
3008        && FindProcShort (glNamedBufferSubData)
3009        && FindProcShort (glCopyNamedBufferSubData)
3010        && FindProcShort (glClearNamedBufferData)
3011        && FindProcShort (glClearNamedBufferSubData)
3012        && FindProcShort (glMapNamedBuffer)
3013        && FindProcShort (glMapNamedBufferRange)
3014        && FindProcShort (glUnmapNamedBuffer)
3015        && FindProcShort (glFlushMappedNamedBufferRange)
3016        && FindProcShort (glGetNamedBufferParameteriv)
3017        && FindProcShort (glGetNamedBufferParameteri64v)
3018        && FindProcShort (glGetNamedBufferPointerv)
3019        && FindProcShort (glGetNamedBufferSubData)
3020        && FindProcShort (glCreateFramebuffers)
3021        && FindProcShort (glNamedFramebufferRenderbuffer)
3022        && FindProcShort (glNamedFramebufferParameteri)
3023        && FindProcShort (glNamedFramebufferTexture)
3024        && FindProcShort (glNamedFramebufferTextureLayer)
3025        && FindProcShort (glNamedFramebufferDrawBuffer)
3026        && FindProcShort (glNamedFramebufferDrawBuffers)
3027        && FindProcShort (glNamedFramebufferReadBuffer)
3028        && FindProcShort (glInvalidateNamedFramebufferData)
3029        && FindProcShort (glInvalidateNamedFramebufferSubData)
3030        && FindProcShort (glClearNamedFramebufferiv)
3031        && FindProcShort (glClearNamedFramebufferuiv)
3032        && FindProcShort (glClearNamedFramebufferfv)
3033        && FindProcShort (glClearNamedFramebufferfi)
3034        && FindProcShort (glBlitNamedFramebuffer)
3035        && FindProcShort (glCheckNamedFramebufferStatus)
3036        && FindProcShort (glGetNamedFramebufferParameteriv)
3037        && FindProcShort (glGetNamedFramebufferAttachmentParameteriv)
3038        && FindProcShort (glCreateRenderbuffers)
3039        && FindProcShort (glNamedRenderbufferStorage)
3040        && FindProcShort (glNamedRenderbufferStorageMultisample)
3041        && FindProcShort (glGetNamedRenderbufferParameteriv)
3042        && FindProcShort (glCreateTextures)
3043        && FindProcShort (glTextureBuffer)
3044        && FindProcShort (glTextureBufferRange)
3045        && FindProcShort (glTextureStorage1D)
3046        && FindProcShort (glTextureStorage2D)
3047        && FindProcShort (glTextureStorage3D)
3048        && FindProcShort (glTextureStorage2DMultisample)
3049        && FindProcShort (glTextureStorage3DMultisample)
3050        && FindProcShort (glTextureSubImage1D)
3051        && FindProcShort (glTextureSubImage2D)
3052        && FindProcShort (glTextureSubImage3D)
3053        && FindProcShort (glCompressedTextureSubImage1D)
3054        && FindProcShort (glCompressedTextureSubImage2D)
3055        && FindProcShort (glCompressedTextureSubImage3D)
3056        && FindProcShort (glCopyTextureSubImage1D)
3057        && FindProcShort (glCopyTextureSubImage2D)
3058        && FindProcShort (glCopyTextureSubImage3D)
3059        && FindProcShort (glTextureParameterf)
3060        && FindProcShort (glTextureParameterfv)
3061        && FindProcShort (glTextureParameteri)
3062        && FindProcShort (glTextureParameterIiv)
3063        && FindProcShort (glTextureParameterIuiv)
3064        && FindProcShort (glTextureParameteriv)
3065        && FindProcShort (glGenerateTextureMipmap)
3066        && FindProcShort (glBindTextureUnit)
3067        && FindProcShort (glGetTextureImage)
3068        && FindProcShort (glGetCompressedTextureImage)
3069        && FindProcShort (glGetTextureLevelParameterfv)
3070        && FindProcShort (glGetTextureLevelParameteriv)
3071        && FindProcShort (glGetTextureParameterfv)
3072        && FindProcShort (glGetTextureParameterIiv)
3073        && FindProcShort (glGetTextureParameterIuiv)
3074        && FindProcShort (glGetTextureParameteriv)
3075        && FindProcShort (glCreateVertexArrays)
3076        && FindProcShort (glDisableVertexArrayAttrib)
3077        && FindProcShort (glEnableVertexArrayAttrib)
3078        && FindProcShort (glVertexArrayElementBuffer)
3079        && FindProcShort (glVertexArrayVertexBuffer)
3080        && FindProcShort (glVertexArrayVertexBuffers)
3081        && FindProcShort (glVertexArrayAttribBinding)
3082        && FindProcShort (glVertexArrayAttribFormat)
3083        && FindProcShort (glVertexArrayAttribIFormat)
3084        && FindProcShort (glVertexArrayAttribLFormat)
3085        && FindProcShort (glVertexArrayBindingDivisor)
3086        && FindProcShort (glGetVertexArrayiv)
3087        && FindProcShort (glGetVertexArrayIndexediv)
3088        && FindProcShort (glGetVertexArrayIndexed64iv)
3089        && FindProcShort (glCreateSamplers)
3090        && FindProcShort (glCreateProgramPipelines)
3091        && FindProcShort (glCreateQueries)
3092        && FindProcShort (glGetQueryBufferObjecti64v)
3093        && FindProcShort (glGetQueryBufferObjectiv)
3094        && FindProcShort (glGetQueryBufferObjectui64v)
3095        && FindProcShort (glGetQueryBufferObjectuiv)
3096        && FindProcShort (glMemoryBarrierByRegion)
3097        && FindProcShort (glGetTextureSubImage)
3098        && FindProcShort (glGetCompressedTextureSubImage)
3099        && FindProcShort (glGetGraphicsResetStatus)
3100        && FindProcShort (glGetnCompressedTexImage)
3101        && FindProcShort (glGetnTexImage)
3102        && FindProcShort (glGetnUniformdv)
3103        && FindProcShort (glGetnUniformfv)
3104        && FindProcShort (glGetnUniformiv)
3105        && FindProcShort (glGetnUniformuiv)
3106        && FindProcShort (glReadnPixels)
3107        && FindProcShort (glGetnMapdv)
3108        && FindProcShort (glGetnMapfv)
3109        && FindProcShort (glGetnMapiv)
3110        && FindProcShort (glGetnPixelMapfv)
3111        && FindProcShort (glGetnPixelMapuiv)
3112        && FindProcShort (glGetnPixelMapusv)
3113        && FindProcShort (glGetnPolygonStipple)
3114        && FindProcShort (glGetnColorTable)
3115        && FindProcShort (glGetnConvolutionFilter)
3116        && FindProcShort (glGetnSeparableFilter)
3117        && FindProcShort (glGetnHistogram)
3118        && FindProcShort (glGetnMinmax)
3119        && FindProcShort (glTextureBarrier);
3120   if (has45)
3121   {
3122     core45 = (OpenGl_GlCore45* )(&(*myFuncs));
3123     if (!isCoreProfile)
3124     {
3125       core45back = (OpenGl_GlCore45Back* )(&(*myFuncs));
3126     }
3127   }
3128   else
3129   {
3130     checkWrongVersion (4, 5, aLastFailedProc);
3131   }
3132
3133   // initialize debug context extension
3134   if (CheckExtension ("GL_ARB_debug_output"))
3135   {
3136     arbDbg = NULL;
3137     if (has43)
3138     {
3139       arbDbg = (OpenGl_ArbDbg* )(&(*myFuncs));
3140     }
3141     else if (FindProc ("glDebugMessageControlARB",  myFuncs->glDebugMessageControl)
3142           && FindProc ("glDebugMessageInsertARB",   myFuncs->glDebugMessageInsert)
3143           && FindProc ("glDebugMessageCallbackARB", myFuncs->glDebugMessageCallback)
3144           && FindProc ("glGetDebugMessageLogARB",   myFuncs->glGetDebugMessageLog))
3145     {
3146       arbDbg = (OpenGl_ArbDbg* )(&(*myFuncs));
3147     }
3148
3149     if (arbDbg != NULL
3150      && caps->contextDebug)
3151     {
3152       // setup default callback
3153       myIsGlDebugCtx = Standard_True;
3154       arbDbg->glDebugMessageCallback (debugCallbackWrap, this);
3155       if (has43)
3156       {
3157         ::glEnable (GL_DEBUG_OUTPUT);
3158       }
3159       if (caps->contextSyncDebug)
3160       {
3161         ::glEnable (GL_DEBUG_OUTPUT_SYNCHRONOUS);
3162       }
3163     }
3164   }
3165
3166   // initialize FBO extension (ARB)
3167   if (hasFBO)
3168   {
3169     arbFBO     = (OpenGl_ArbFBO*     )(&(*myFuncs));
3170     arbFBOBlit = (OpenGl_ArbFBOBlit* )(&(*myFuncs));
3171     extPDS = Standard_True; // extension for EXT, but part of ARB
3172   }
3173
3174   // initialize GS extension (EXT)
3175   if (CheckExtension ("GL_EXT_geometry_shader4")
3176    && FindProcShort (glProgramParameteriEXT))
3177   {
3178     extGS = (OpenGl_ExtGS* )(&(*myFuncs));
3179   }
3180
3181   // initialize bindless texture extension (ARB)
3182   if (CheckExtension ("GL_ARB_bindless_texture")
3183    && FindProcShort (glGetTextureHandleARB)
3184    && FindProcShort (glGetTextureSamplerHandleARB)
3185    && FindProcShort (glMakeTextureHandleResidentARB)
3186    && FindProcShort (glMakeTextureHandleNonResidentARB)
3187    && FindProcShort (glGetImageHandleARB)
3188    && FindProcShort (glMakeImageHandleResidentARB)
3189    && FindProcShort (glMakeImageHandleNonResidentARB)
3190    && FindProcShort (glUniformHandleui64ARB)
3191    && FindProcShort (glUniformHandleui64vARB)
3192    && FindProcShort (glProgramUniformHandleui64ARB)
3193    && FindProcShort (glProgramUniformHandleui64vARB)
3194    && FindProcShort (glIsTextureHandleResidentARB)
3195    && FindProcShort (glIsImageHandleResidentARB)
3196    && FindProcShort (glVertexAttribL1ui64ARB)
3197    && FindProcShort (glVertexAttribL1ui64vARB)
3198    && FindProcShort (glGetVertexAttribLui64vARB))
3199   {
3200     arbTexBindless = (OpenGl_ArbTexBindless* )(&(*myFuncs));
3201   }
3202
3203   if (has30)
3204   {
3205     // MSAA RenderBuffers have been defined in OpenGL 3.0,
3206     // but MSAA Textures - only in OpenGL 3.2+
3207     if (!has32
3208      && CheckExtension ("GL_ARB_texture_multisample")
3209      && FindProcShort (glTexImage2DMultisample))
3210     {
3211       GLint aNbColorSamples = 0, aNbDepthSamples = 0;
3212       ::glGetIntegerv (GL_MAX_COLOR_TEXTURE_SAMPLES, &aNbColorSamples);
3213       ::glGetIntegerv (GL_MAX_DEPTH_TEXTURE_SAMPLES, &aNbDepthSamples);
3214       myMaxMsaaSamples = Min (aNbColorSamples, aNbDepthSamples);
3215     }
3216     if (!has43
3217      && CheckExtension ("GL_ARB_texture_storage_multisample")
3218      && FindProcShort (glTexStorage2DMultisample))
3219     {
3220       //
3221     }
3222   }
3223
3224   // check whether ray tracing mode is supported
3225   myHasRayTracing = has31
3226                  && arbTboRGB32
3227                  && arbFBOBlit  != NULL;
3228
3229   // check whether textures in ray tracing mode are supported
3230   myHasRayTracingTextures = myHasRayTracing
3231                          && arbTexBindless != NULL;
3232
3233   // check whether adaptive screen sampling in ray tracing mode is supported
3234   myHasRayTracingAdaptiveSampling = myHasRayTracing
3235                                  && has44;
3236   myHasRayTracingAdaptiveSamplingAtomic = myHasRayTracingAdaptiveSampling
3237                                        && CheckExtension ("GL_NV_shader_atomic_float");
3238 #endif
3239
3240   if (arbFBO != NULL
3241    && hasFboSRGB)
3242   {
3243     // Detect if window buffer is considered by OpenGL as sRGB-ready
3244     // (linear RGB color written by shader is automatically converted into sRGB)
3245     // or not (offscreen FBO should be blit into window buffer with gamma correction).
3246     const GLenum aDefWinBuffer =
3247     #if !defined(GL_ES_VERSION_2_0)
3248       GL_BACK_LEFT;
3249     #else
3250       GL_BACK;
3251     #endif
3252     GLint aWinColorEncoding = 0; // GL_LINEAR
3253     arbFBO->glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER, aDefWinBuffer, GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, &aWinColorEncoding);
3254     ResetErrors (true);
3255     myIsSRgbWindow = aWinColorEncoding == GL_SRGB;
3256
3257     // On desktop OpenGL, pixel formats are almost always sRGB-ready, even when not requested;
3258     // it is safe behavior on desktop where GL_FRAMEBUFFER_SRGB is disabled by default
3259     // (contrary to OpenGL ES, where it is enabled by default).
3260     // NVIDIA drivers, however, always return GL_LINEAR even for sRGB-ready pixel formats on Windows platform,
3261     // while AMD and Intel report GL_SRGB as expected.
3262     // macOS drivers seems to be also report GL_LINEAR even for [NSColorSpace sRGBColorSpace].
3263   #if !defined(GL_ES_VERSION_2_0)
3264   #ifdef __APPLE__
3265     myIsSRgbWindow = true;
3266   #else
3267     if (!myIsSRgbWindow
3268       && myVendor.Search ("nvidia") != -1)
3269     {
3270       myIsSRgbWindow = true;
3271     }
3272   #endif
3273   #endif
3274     if (!myIsSRgbWindow)
3275     {
3276       Message::SendTrace ("OpenGl_Context, warning: window buffer is not sRGB-ready.\n"
3277                           "Check OpenGL window creation parameters for optimal performance.");
3278     }
3279   }
3280
3281   if (arbTexFloat)
3282   {
3283     mySupportedFormats->Add (Image_Format_GrayF);
3284     mySupportedFormats->Add (Image_Format_AlphaF);
3285     mySupportedFormats->Add (Image_Format_RGBF);
3286     mySupportedFormats->Add (Image_Format_RGBAF);
3287     if (arbTexRG)
3288     {
3289       mySupportedFormats->Add (Image_Format_RGF);
3290     }
3291     if (extBgra)
3292     {
3293     #if !defined(GL_ES_VERSION_2_0)
3294       mySupportedFormats->Add (Image_Format_BGRF);
3295     #endif
3296       mySupportedFormats->Add (Image_Format_BGRAF);
3297     }
3298   }
3299
3300 #ifdef __EMSCRIPTEN__
3301   if (checkEnableWebGlExtension (*this, "GL_WEBGL_compressed_texture_s3tc")) // GL_WEBGL_compressed_texture_s3tc_srgb for sRGB formats
3302   {
3303     mySupportedFormats->Add (Image_CompressedFormat_RGB_S3TC_DXT1);
3304     mySupportedFormats->Add (Image_CompressedFormat_RGBA_S3TC_DXT1);
3305     mySupportedFormats->Add (Image_CompressedFormat_RGBA_S3TC_DXT3);
3306     mySupportedFormats->Add (Image_CompressedFormat_RGBA_S3TC_DXT5);
3307   }
3308 #else
3309   if (CheckExtension ("GL_EXT_texture_compression_s3tc")) // GL_EXT_texture_sRGB for sRGB formats
3310   {
3311     mySupportedFormats->Add (Image_CompressedFormat_RGB_S3TC_DXT1);
3312     mySupportedFormats->Add (Image_CompressedFormat_RGBA_S3TC_DXT1);
3313     mySupportedFormats->Add (Image_CompressedFormat_RGBA_S3TC_DXT3);
3314     mySupportedFormats->Add (Image_CompressedFormat_RGBA_S3TC_DXT5);
3315   }
3316   else
3317   {
3318     if (CheckExtension ("GL_EXT_texture_compression_dxt1"))
3319     {
3320       mySupportedFormats->Add (Image_CompressedFormat_RGB_S3TC_DXT1);
3321       mySupportedFormats->Add (Image_CompressedFormat_RGBA_S3TC_DXT1);
3322     }
3323     if (CheckExtension ("GL_ANGLE_texture_compression_dxt3"))
3324     {
3325       mySupportedFormats->Add (Image_CompressedFormat_RGBA_S3TC_DXT3);
3326     }
3327     if (CheckExtension ("GL_ANGLE_texture_compression_dxt5"))
3328     {
3329       mySupportedFormats->Add (Image_CompressedFormat_RGBA_S3TC_DXT5);
3330     }
3331   }
3332 #endif
3333
3334   // check whether PBR shading model is supported
3335   myHasPBR = arbFBO != NULL
3336           && myMaxTexCombined >= 4
3337           && arbTexRG
3338           && arbTexFloat
3339           && (IsGlGreaterEqual (3, 0)
3340         #if !defined(GL_ES_VERSION_2_0)
3341           || (IsGlGreaterEqual (2, 1) && CheckExtension ("GL_EXT_gpu_shader4"))
3342         #endif
3343              );
3344   if (myHasPBR)
3345   {
3346     myPBREnvLUTTexUnit       = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined + Graphic3d_TextureUnit_PbrEnvironmentLUT);
3347     myPBRDiffIBLMapSHTexUnit = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined + Graphic3d_TextureUnit_PbrIblDiffuseSH);
3348     myPBRSpecIBLMapTexUnit   = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined + Graphic3d_TextureUnit_PbrIblSpecular);
3349   }
3350 }
3351
3352 // =======================================================================
3353 // function : MemoryInfo
3354 // purpose  :
3355 // =======================================================================
3356 Standard_Size OpenGl_Context::AvailableMemory() const
3357 {
3358 #if !defined(GL_ES_VERSION_2_0)
3359   if (atiMem)
3360   {
3361     // this is actually information for VBO pool
3362     // however because pools are mostly shared
3363     // it can be used for total GPU memory estimations
3364     GLint aMemInfo[4];
3365     aMemInfo[0] = 0;
3366     glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aMemInfo);
3367     // returned value is in KiB, however this maybe changed in future
3368     return Standard_Size(aMemInfo[0]) * 1024;
3369   }
3370   else if (nvxMem)
3371   {
3372     // current available dedicated video memory (in KiB), currently unused GPU memory
3373     GLint aMemInfo = 0;
3374     glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aMemInfo);
3375     return Standard_Size(aMemInfo) * 1024;
3376   }
3377 #endif
3378   return 0;
3379 }
3380
3381 // =======================================================================
3382 // function : MemoryInfo
3383 // purpose  :
3384 // =======================================================================
3385 TCollection_AsciiString OpenGl_Context::MemoryInfo() const
3386 {
3387   TColStd_IndexedDataMapOfStringString aDict;
3388   MemoryInfo (aDict);
3389
3390   TCollection_AsciiString aText;
3391   for (TColStd_IndexedDataMapOfStringString::Iterator anIter (aDict); anIter.More(); anIter.Next())
3392   {
3393     if (!aText.IsEmpty())
3394     {
3395       aText += "\n";
3396     }
3397     aText += TCollection_AsciiString("  ") + anIter.Key() + ": " + anIter.Value();
3398   }
3399   return aText;
3400 }
3401
3402 // =======================================================================
3403 // function : MemoryInfo
3404 // purpose  :
3405 // =======================================================================
3406 void OpenGl_Context::MemoryInfo (TColStd_IndexedDataMapOfStringString& theDict) const
3407 {
3408 #if defined(GL_ES_VERSION_2_0)
3409   (void )theDict;
3410 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
3411   GLint aGlRendId = 0;
3412   CGLGetParameter (CGLGetCurrentContext(), kCGLCPCurrentRendererID, &aGlRendId);
3413
3414   CGLRendererInfoObj  aRendObj = NULL;
3415   CGOpenGLDisplayMask aDispMask = CGDisplayIDToOpenGLDisplayMask (kCGDirectMainDisplay);
3416   GLint aRendNb = 0;
3417   CGLQueryRendererInfo (aDispMask, &aRendObj, &aRendNb);
3418   for (GLint aRendIter = 0; aRendIter < aRendNb; ++aRendIter)
3419   {
3420     GLint aRendId = 0;
3421     if (CGLDescribeRenderer (aRendObj, aRendIter, kCGLRPRendererID, &aRendId) != kCGLNoError
3422      || aRendId != aGlRendId)
3423     {
3424       continue;
3425     }
3426
3427     //kCGLRPVideoMemoryMegabytes   = 131;
3428     //kCGLRPTextureMemoryMegabytes = 132;
3429     GLint aVMem = 0;
3430   #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
3431     if (CGLDescribeRenderer(aRendObj, aRendIter, kCGLRPVideoMemoryMegabytes, &aVMem) == kCGLNoError)
3432     {
3433       addInfo (theDict, "GPU memory",         TCollection_AsciiString() + aVMem + " MiB");
3434     }
3435     if (CGLDescribeRenderer(aRendObj, aRendIter, kCGLRPTextureMemoryMegabytes, &aVMem) == kCGLNoError)
3436     {
3437       addInfo (theDict, "GPU Texture memory", TCollection_AsciiString() + aVMem + " MiB");
3438     }
3439   #else
3440     if (CGLDescribeRenderer(aRendObj, aRendIter, kCGLRPVideoMemory, &aVMem) == kCGLNoError)
3441     {
3442       addInfo (theDict, "GPU memory",         TCollection_AsciiString() + (aVMem / (1024 * 1024)) + " MiB");
3443     }
3444     if (CGLDescribeRenderer(aRendObj, aRendIter, kCGLRPTextureMemory, &aVMem) == kCGLNoError)
3445     {
3446       addInfo (theDict, "GPU Texture memory", TCollection_AsciiString() + (aVMem / (1024 * 1024)) + " MiB");
3447     }
3448   #endif
3449   }
3450 #endif
3451
3452 #if !defined(GL_ES_VERSION_2_0)
3453   if (atiMem)
3454   {
3455     GLint aValues[4];
3456     memset (aValues, 0, sizeof(aValues));
3457     glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aValues);
3458
3459     // total memory free in the pool
3460     addInfo (theDict, "GPU free memory",    TCollection_AsciiString() + (aValues[0] / 1024) + " MiB");
3461
3462     if (aValues[1] != aValues[0])
3463     {
3464       // largest available free block in the pool
3465       addInfo (theDict, "Largest free block", TCollection_AsciiString() + (aValues[1] / 1024) + " MiB");
3466     }
3467     if (aValues[2] != aValues[0])
3468     {
3469       // total auxiliary memory free
3470       addInfo (theDict, "Free auxiliary memory", TCollection_AsciiString() + (aValues[2] / 1024) + " MiB");
3471     }
3472   }
3473   else if (nvxMem)
3474   {
3475     //current available dedicated video memory (in KiB), currently unused GPU memory
3476     GLint aValue = 0;
3477     glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aValue);
3478     addInfo (theDict, "GPU free memory", TCollection_AsciiString() + (aValue / 1024) + " MiB");
3479
3480     // dedicated video memory, total size (in KiB) of the GPU memory
3481     GLint aDedicated = 0;
3482     glGetIntegerv (GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &aDedicated);
3483     addInfo (theDict, "GPU memory", TCollection_AsciiString() + (aDedicated / 1024) + " MiB");
3484
3485     // total available memory, total size (in KiB) of the memory available for allocations
3486     glGetIntegerv (GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &aValue);
3487     if (aValue != aDedicated)
3488     {
3489       // different only for special configurations
3490       addInfo (theDict, "Total memory", TCollection_AsciiString() + (aValue / 1024) + " MiB");
3491     }
3492   }
3493 #if defined(_WIN32)
3494   else if (myFuncs->wglGetGPUInfoAMD != NULL
3495         && myFuncs->wglGetContextGPUIDAMD != NULL)
3496   {
3497     GLuint aTotalMemMiB = 0;
3498     UINT anAmdId = myFuncs->wglGetContextGPUIDAMD ((HGLRC )myGContext);
3499     if (anAmdId != 0)
3500     {
3501       if (myFuncs->wglGetGPUInfoAMD (anAmdId, WGL_GPU_RAM_AMD, GL_UNSIGNED_INT, sizeof(aTotalMemMiB), &aTotalMemMiB) > 0)
3502       {
3503         addInfo (theDict, "GPU memory", TCollection_AsciiString() + (int )aTotalMemMiB + " MiB");
3504       }
3505     }
3506   }
3507 #endif
3508 #endif
3509
3510 #if !defined(GL_ES_VERSION_2_0) && !defined(__APPLE__) && !defined(_WIN32)
3511   // GLX_RENDERER_VENDOR_ID_MESA
3512   if (myFuncs->glXQueryCurrentRendererIntegerMESA != NULL)
3513   {
3514     unsigned int aVMemMiB = 0;
3515     if (myFuncs->glXQueryCurrentRendererIntegerMESA (GLX_RENDERER_VIDEO_MEMORY_MESA, &aVMemMiB) != False)
3516     {
3517       addInfo (theDict, "GPU memory", TCollection_AsciiString() + int(aVMemMiB) + " MiB");
3518     }
3519   }
3520 #endif
3521 }
3522
3523 // =======================================================================
3524 // function : DiagnosticInfo
3525 // purpose  :
3526 // =======================================================================
3527 void OpenGl_Context::DiagnosticInformation (TColStd_IndexedDataMapOfStringString& theDict,
3528                                             Graphic3d_DiagnosticInfo theFlags) const
3529 {
3530   if ((theFlags & Graphic3d_DiagnosticInfo_NativePlatform) != 0)
3531   {
3532   #if defined(HAVE_EGL)
3533     addInfo (theDict, "EGLVersion",    ::eglQueryString ((EGLDisplay )myDisplay, EGL_VERSION));
3534     addInfo (theDict, "EGLVendor",     ::eglQueryString ((EGLDisplay )myDisplay, EGL_VENDOR));
3535     addInfo (theDict, "EGLClientAPIs", ::eglQueryString ((EGLDisplay )myDisplay, EGL_CLIENT_APIS));
3536     if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0)
3537     {
3538       addInfo (theDict, "EGLExtensions", ::eglQueryString ((EGLDisplay )myDisplay, EGL_EXTENSIONS));
3539     }
3540   #elif defined(_WIN32)
3541     if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0
3542      && myFuncs->wglGetExtensionsStringARB != NULL)
3543     {
3544       const char* aWglExts = myFuncs->wglGetExtensionsStringARB ((HDC )myWindowDC);
3545       addInfo (theDict, "WGLExtensions", aWglExts);
3546     }
3547   #elif defined(__APPLE__)
3548     //
3549   #else
3550     Display* aDisplay = (Display*)myDisplay;
3551     const int aScreen = DefaultScreen(aDisplay);
3552     addInfo (theDict, "GLXDirectRendering", ::glXIsDirect (aDisplay, (GLXContext )myGContext) ? "Yes" : "No");
3553     addInfo (theDict, "GLXVendor",  ::glXQueryServerString (aDisplay, aScreen, GLX_VENDOR));
3554     addInfo (theDict, "GLXVersion", ::glXQueryServerString (aDisplay, aScreen, GLX_VERSION));
3555     if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0)
3556     {
3557       const char* aGlxExts = ::glXQueryExtensionsString (aDisplay, aScreen);
3558       addInfo(theDict, "GLXExtensions", aGlxExts);
3559     }
3560
3561     addInfo (theDict, "GLXClientVendor",  ::glXGetClientString (aDisplay, GLX_VENDOR));
3562     addInfo (theDict, "GLXClientVersion", ::glXGetClientString (aDisplay, GLX_VERSION));
3563     if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0)
3564     {
3565       addInfo (theDict, "GLXClientExtensions", ::glXGetClientString (aDisplay, GLX_EXTENSIONS));
3566     }
3567   #endif
3568   }
3569
3570   if ((theFlags & Graphic3d_DiagnosticInfo_Device) != 0)
3571   {
3572     Standard_Integer aDriverVer[2] = {};
3573     ReadGlVersion (aDriverVer[0], aDriverVer[1]);
3574     addInfo (theDict, "GLvendor",    (const char*)::glGetString (GL_VENDOR));
3575     addInfo (theDict, "GLdevice",    (const char*)::glGetString (GL_RENDERER));
3576   #ifdef __EMSCRIPTEN__
3577     if (checkEnableWebGlExtension (*this, "GL_WEBGL_debug_renderer_info"))
3578     {
3579       if (const char* aVendor = (const char*)::glGetString (0x9245))
3580       {
3581         addInfo (theDict, "GLunmaskedVendor", aVendor);
3582       }
3583       if (const char* aDevice = (const char*)::glGetString (0x9246))
3584       {
3585         addInfo (theDict, "GLunmaskedDevice", aDevice);
3586       }
3587     }
3588   #endif
3589
3590     addInfo (theDict, "GLversion",   (const char*)::glGetString (GL_VERSION));
3591     if (myGlVerMajor != aDriverVer[0]
3592      || myGlVerMinor != aDriverVer[1])
3593     {
3594       addInfo (theDict, "GLversionOcct", TCollection_AsciiString (myGlVerMajor) + "." + TCollection_AsciiString (myGlVerMinor));
3595     }
3596     if (IsGlGreaterEqual (2, 0))
3597     {
3598       addInfo (theDict, "GLSLversion", (const char*)::glGetString (GL_SHADING_LANGUAGE_VERSION));
3599     }
3600     if (myIsGlDebugCtx)
3601     {
3602       addInfo (theDict, "GLdebug", "ON");
3603     }
3604   }
3605
3606   if ((theFlags & Graphic3d_DiagnosticInfo_Limits) != 0)
3607   {
3608     addInfo (theDict, "Max texture size", TCollection_AsciiString(myMaxTexDim));
3609     addInfo (theDict, "Max FBO dump size", TCollection_AsciiString() + myMaxDumpSizeX + "x" + myMaxDumpSizeY);
3610     addInfo (theDict, "Max combined texture units", TCollection_AsciiString(myMaxTexCombined));
3611     addInfo (theDict, "Max MSAA samples", TCollection_AsciiString(myMaxMsaaSamples));
3612   }
3613
3614   if ((theFlags & Graphic3d_DiagnosticInfo_FrameBuffer) != 0)
3615   {
3616     GLint aViewport[4] = {};
3617     ::glGetIntegerv (GL_VIEWPORT, aViewport);
3618     addInfo (theDict, "Viewport", TCollection_AsciiString() + aViewport[2] + "x" + aViewport[3]);
3619   }
3620
3621   if ((theFlags & Graphic3d_DiagnosticInfo_Memory) != 0)
3622   {
3623     MemoryInfo (theDict);
3624   }
3625
3626   if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0)
3627   {
3628   #if !defined(GL_ES_VERSION_2_0)
3629     if (IsGlGreaterEqual (3, 0)
3630      && myFuncs->glGetStringi != NULL)
3631     {
3632       TCollection_AsciiString anExtList;
3633       GLint anExtNb = 0;
3634       ::glGetIntegerv (GL_NUM_EXTENSIONS, &anExtNb);
3635       for (GLint anIter = 0; anIter < anExtNb; ++anIter)
3636       {
3637         const char* anExtension = (const char*)myFuncs->glGetStringi (GL_EXTENSIONS, (GLuint)anIter);
3638         if (!anExtList.IsEmpty())
3639         {
3640           anExtList += " ";
3641         }
3642         anExtList += anExtension;
3643       }
3644       addInfo(theDict, "GLextensions", anExtList);
3645     }
3646     else
3647   #endif
3648     {
3649       addInfo (theDict, "GLextensions", (const char*)::glGetString (GL_EXTENSIONS));
3650     }
3651   }
3652 }
3653
3654 // =======================================================================
3655 // function : GetResource
3656 // purpose  :
3657 // =======================================================================
3658 const Handle(OpenGl_Resource)& OpenGl_Context::GetResource (const TCollection_AsciiString& theKey) const
3659 {
3660   return mySharedResources->IsBound (theKey) ? mySharedResources->Find (theKey) : NULL_GL_RESOURCE;
3661 }
3662
3663 // =======================================================================
3664 // function : ShareResource
3665 // purpose  :
3666 // =======================================================================
3667 Standard_Boolean OpenGl_Context::ShareResource (const TCollection_AsciiString& theKey,
3668                                                 const Handle(OpenGl_Resource)& theResource)
3669 {
3670   if (theKey.IsEmpty() || theResource.IsNull())
3671   {
3672     return Standard_False;
3673   }
3674   return mySharedResources->Bind (theKey, theResource);
3675 }
3676
3677 // =======================================================================
3678 // function : ReleaseResource
3679 // purpose  :
3680 // =======================================================================
3681 void OpenGl_Context::ReleaseResource (const TCollection_AsciiString& theKey,
3682                                       const Standard_Boolean         theToDelay)
3683 {
3684   if (!mySharedResources->IsBound (theKey))
3685   {
3686     return;
3687   }
3688   const Handle(OpenGl_Resource)& aRes = mySharedResources->Find (theKey);
3689   if (aRes->GetRefCount() > 1)
3690   {
3691     return;
3692   }
3693
3694   if (theToDelay)
3695   {
3696     myDelayed->Bind (theKey, 1);
3697   }
3698   else
3699   {
3700     aRes->Release (this);
3701     mySharedResources->UnBind (theKey);
3702   }
3703 }
3704
3705 // =======================================================================
3706 // function : ReleaseDelayed
3707 // purpose  :
3708 // =======================================================================
3709 void OpenGl_Context::ReleaseDelayed()
3710 {
3711   // release queued elements
3712   while (!myUnusedResources->IsEmpty())
3713   {
3714     myUnusedResources->First()->Release (this);
3715     myUnusedResources->RemoveFirst();
3716   }
3717
3718   // release delayed shared resources
3719   NCollection_Vector<TCollection_AsciiString> aDeadList;
3720   for (NCollection_DataMap<TCollection_AsciiString, Standard_Integer>::Iterator anIter (*myDelayed);
3721        anIter.More(); anIter.Next())
3722   {
3723     if (++anIter.ChangeValue() <= 2)
3724     {
3725       continue; // postpone release one more frame to ensure noone use it periodically
3726     }
3727
3728     const TCollection_AsciiString& aKey = anIter.Key();
3729     if (!mySharedResources->IsBound (aKey))
3730     {
3731       // mixed unshared strategy delayed/undelayed was used!
3732       aDeadList.Append (aKey);
3733       continue;
3734     }
3735
3736     const Handle(OpenGl_Resource)& aRes = mySharedResources->ChangeFind (aKey);
3737     if (aRes->GetRefCount() > 1)
3738     {
3739       // should be only 1 instance in mySharedResources
3740       // if not - resource was reused again
3741       aDeadList.Append (aKey);
3742       continue;
3743     }
3744
3745     // release resource if no one requiested it more than 2 redraw calls
3746     aRes->Release (this);
3747     mySharedResources->UnBind (aKey);
3748     aDeadList.Append (aKey);
3749   }
3750
3751   for (Standard_Integer anIter = 0; anIter < aDeadList.Length(); ++anIter)
3752   {
3753     myDelayed->UnBind (aDeadList.Value (anIter));
3754   }
3755 }
3756
3757 // =======================================================================
3758 // function : BindTextures
3759 // purpose  :
3760 // =======================================================================
3761 Handle(OpenGl_TextureSet) OpenGl_Context::BindTextures (const Handle(OpenGl_TextureSet)& theTextures,
3762                                                         const Handle(OpenGl_ShaderProgram)& theProgram)
3763 {
3764   const Standard_Integer aTextureSetBits = !theTextures.IsNull() ? theTextures->TextureSetBits() : 0;
3765   const Standard_Integer aProgramBits    = !theProgram.IsNull() ? theProgram->TextureSetBits() : 0;
3766   Standard_Integer aMissingBits = aProgramBits & ~aTextureSetBits;
3767   if (aMissingBits != 0
3768    && myTextureRgbaBlack.IsNull())
3769   {
3770     // allocate mock textures
3771     myTextureRgbaBlack = new OpenGl_Texture();
3772     myTextureRgbaWhite = new OpenGl_Texture();
3773     Image_PixMap anImage;
3774     anImage.InitZero (Image_Format_RGBA, 2, 2, 0, (Standard_Byte )0);
3775     if (!myTextureRgbaBlack->Init (this, OpenGl_TextureFormat::Create<GLubyte, 4>(), Graphic3d_Vec2i (2, 2), Graphic3d_TOT_2D, &anImage))
3776     {
3777       PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH,
3778                     "Error: unable to create unit mock PBR texture map.");
3779     }
3780     anImage.InitZero (Image_Format_RGBA, 2, 2, 0, (Standard_Byte )255);
3781     if (!myTextureRgbaWhite->Init (this, OpenGl_TextureFormat::Create<GLubyte, 4>(), Graphic3d_Vec2i (2, 2), Graphic3d_TOT_2D, &anImage))
3782     {
3783       PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH,
3784                     "Error: unable to create normal mock PBR texture map.");
3785     }
3786   }
3787
3788   Handle(OpenGl_TextureSet) anOldTextures = myActiveTextures;
3789   if (myActiveTextures != theTextures)
3790   {
3791     Handle(OpenGl_Context) aThisCtx (this);
3792     for (OpenGl_TextureSetPairIterator aSlotIter (myActiveTextures, theTextures); aSlotIter.More(); aSlotIter.Next())
3793     {
3794       const Graphic3d_TextureUnit aTexUnit = aSlotIter.Unit();
3795       const OpenGl_Texture* aTextureOld = aSlotIter.Texture1();
3796       const OpenGl_Texture* aTextureNew = aSlotIter.Texture2();
3797       if (aTextureNew == aTextureOld)
3798       {
3799         continue;
3800       }
3801
3802       if (aTextureNew != NULL
3803        && aTextureNew->IsValid())
3804       {
3805         if (aTexUnit >= myMaxTexCombined)
3806         {
3807           PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
3808                        TCollection_AsciiString("Texture unit ") + aTexUnit + " for " + aTextureNew->ResourceId() + " exceeds hardware limit " + myMaxTexCombined);
3809           continue;
3810         }
3811
3812         aTextureNew->Bind (aThisCtx, aTexUnit);
3813         if (aTextureNew->Sampler()->ToUpdateParameters())
3814         {
3815           if (aTextureNew->Sampler()->IsImmutable())
3816           {
3817             aTextureNew->Sampler()->Init (aThisCtx, *aTextureNew);
3818           }
3819           else
3820           {
3821             OpenGl_Sampler::applySamplerParams (aThisCtx, aTextureNew->Sampler()->Parameters(), aTextureNew->Sampler().get(), aTextureNew->GetTarget(), aTextureNew->MaxMipmapLevel());
3822           }
3823         }
3824       #if !defined(GL_ES_VERSION_2_0)
3825         if (core11 != NULL)
3826         {
3827           OpenGl_Sampler::applyGlobalTextureParams (aThisCtx, *aTextureNew, aTextureNew->Sampler()->Parameters());
3828         }
3829       #endif
3830       }
3831       else if (aTextureOld != NULL
3832             && aTextureOld->IsValid())
3833       {
3834         aTextureOld->Unbind (aThisCtx, aTexUnit);
3835       #if !defined(GL_ES_VERSION_2_0)
3836         if (core11 != NULL)
3837         {
3838           OpenGl_Sampler::resetGlobalTextureParams (aThisCtx, *aTextureOld, aTextureOld->Sampler()->Parameters());
3839         }
3840       #endif
3841       }
3842     }
3843     myActiveTextures = theTextures;
3844   }
3845
3846   if (myActiveMockTextures != aMissingBits)
3847   {
3848     myActiveMockTextures = aMissingBits;
3849     for (Standard_Integer aBitIter = 0; aMissingBits != 0; ++aBitIter)
3850     {
3851       Standard_Integer aUnitMask = 1 << aBitIter;
3852       if ((aUnitMask & aMissingBits) != 0)
3853       {
3854         aMissingBits = aMissingBits & ~aUnitMask;
3855         if (aBitIter == Graphic3d_TextureUnit_Normal)
3856         {
3857           myTextureRgbaBlack->Bind (this, static_cast<Graphic3d_TextureUnit>(aBitIter));
3858         }
3859         else
3860         {
3861           myTextureRgbaWhite->Bind (this, static_cast<Graphic3d_TextureUnit>(aBitIter));
3862         }
3863       }
3864     }
3865   }
3866
3867   return anOldTextures;
3868 }
3869
3870 // =======================================================================
3871 // function : BindProgram
3872 // purpose  :
3873 // =======================================================================
3874 Standard_Boolean OpenGl_Context::BindProgram (const Handle(OpenGl_ShaderProgram)& theProgram)
3875 {
3876   if (core20fwd == NULL)
3877   {
3878     return Standard_False;
3879   }
3880   else if (myActiveProgram == theProgram)
3881   {
3882     return Standard_True;
3883   }
3884
3885   if (theProgram.IsNull()
3886   || !theProgram->IsValid())
3887   {
3888     if (!myActiveProgram.IsNull())
3889     {
3890       core20fwd->glUseProgram (OpenGl_ShaderProgram::NO_PROGRAM);
3891       myActiveProgram.Nullify();
3892     }
3893     return Standard_False;
3894   }
3895
3896   myActiveProgram = theProgram;
3897   core20fwd->glUseProgram (theProgram->ProgramId());
3898   return Standard_True;
3899 }
3900
3901 // =======================================================================
3902 // function : BindDefaultVao
3903 // purpose  :
3904 // =======================================================================
3905 void OpenGl_Context::BindDefaultVao()
3906 {
3907 #if !defined(GL_ES_VERSION_2_0)
3908   if (myDefaultVao == 0
3909    || core32 == NULL)
3910   {
3911     return;
3912   }
3913
3914   core32->glBindVertexArray (myDefaultVao);
3915 #endif
3916 }
3917
3918 // =======================================================================
3919 // function : SetDefaultFrameBuffer
3920 // purpose  :
3921 // =======================================================================
3922 Handle(OpenGl_FrameBuffer) OpenGl_Context::SetDefaultFrameBuffer (const Handle(OpenGl_FrameBuffer)& theFbo)
3923 {
3924   Handle(OpenGl_FrameBuffer) aFbo = myDefaultFbo;
3925   myDefaultFbo = theFbo;
3926   return aFbo;
3927 }
3928
3929 // =======================================================================
3930 // function : SetShadingMaterial
3931 // purpose  :
3932 // =======================================================================
3933 void OpenGl_Context::SetShadingMaterial (const OpenGl_Aspects* theAspect,
3934                                          const Handle(Graphic3d_PresentationAttributes)& theHighlight)
3935 {
3936   const Handle(Graphic3d_Aspects)& anAspect = (!theHighlight.IsNull() && !theHighlight->BasicFillAreaAspect().IsNull())
3937                                             ?  (const Handle(Graphic3d_Aspects)& )theHighlight->BasicFillAreaAspect()
3938                                             :  theAspect->Aspect();
3939
3940   const bool toDistinguish = anAspect->Distinguish();
3941   const bool toMapTexture  = anAspect->ToMapTexture();
3942   const Graphic3d_MaterialAspect& aMatFrontSrc = anAspect->FrontMaterial();
3943   const Graphic3d_MaterialAspect& aMatBackSrc  = toDistinguish
3944                                                ? anAspect->BackMaterial()
3945                                                : aMatFrontSrc;
3946   const Quantity_Color& aFrontIntColor = anAspect->InteriorColor();
3947   const Quantity_Color& aBackIntColor  = toDistinguish
3948                                        ? anAspect->BackInteriorColor()
3949                                        : aFrontIntColor;
3950
3951   myMatFront.Init (*this, aMatFrontSrc, aFrontIntColor);
3952   if (toDistinguish)
3953   {
3954     myMatBack.Init (*this, aMatBackSrc, aBackIntColor);
3955   }
3956   else
3957   {
3958     myMatBack = myMatFront;
3959   }
3960
3961   if (!theHighlight.IsNull()
3962     && theHighlight->BasicFillAreaAspect().IsNull())
3963   {
3964     myMatFront.SetColor (theHighlight->ColorRGBA());
3965     myMatBack .SetColor (theHighlight->ColorRGBA());
3966   }
3967
3968   Standard_ShortReal anAlphaFront = 1.0f;
3969   Standard_ShortReal anAlphaBack  = 1.0f;
3970   if (CheckIsTransparent (theAspect, theHighlight, anAlphaFront, anAlphaBack))
3971   {
3972     myMatFront.Common.Diffuse.a() = anAlphaFront;
3973     myMatBack .Common.Diffuse.a() = anAlphaBack;
3974
3975     myMatFront.Pbr.BaseColor.a() = anAlphaFront;
3976     myMatBack .Pbr.BaseColor.a() = anAlphaBack;
3977   }
3978
3979   // do not update material properties in case of zero reflection mode,
3980   // because GL lighting will be disabled by OpenGl_PrimitiveArray::DrawArray() anyway.
3981   const OpenGl_MaterialState& aMatState = myShaderManager->MaterialState();
3982   float anAlphaCutoff = anAspect->AlphaMode() == Graphic3d_AlphaMode_Mask
3983                       ? anAspect->AlphaCutoff()
3984                       : ShortRealLast();
3985   if (anAspect->ToDrawEdges())
3986   {
3987     if (anAspect->InteriorStyle() == Aspect_IS_EMPTY
3988      || (anAspect->InteriorStyle() == Aspect_IS_SOLID
3989       && anAspect->EdgeColorRGBA().Alpha() < 1.0f))
3990     {
3991       anAlphaCutoff = 0.285f;
3992     }
3993   }
3994   if (theAspect->ShadingModel() == Graphic3d_TOSM_UNLIT)
3995   {
3996     if (anAlphaCutoff == aMatState.AlphaCutoff())
3997     {
3998       return;
3999     }
4000   }
4001   else if (myMatFront    == aMatState.FrontMaterial()
4002         && myMatBack     == aMatState.BackMaterial()
4003         && toDistinguish == aMatState.ToDistinguish()
4004         && toMapTexture  == aMatState.ToMapTexture()
4005         && anAlphaCutoff == aMatState.AlphaCutoff())
4006   {
4007     return;
4008   }
4009
4010   myShaderManager->UpdateMaterialStateTo (myMatFront, myMatBack, anAlphaCutoff, toDistinguish, toMapTexture);
4011 }
4012
4013 // =======================================================================
4014 // function : CheckIsTransparent
4015 // purpose  :
4016 // =======================================================================
4017 Standard_Boolean OpenGl_Context::CheckIsTransparent (const OpenGl_Aspects* theAspect,
4018                                                      const Handle(Graphic3d_PresentationAttributes)& theHighlight,
4019                                                      Standard_ShortReal& theAlphaFront,
4020                                                      Standard_ShortReal& theAlphaBack)
4021 {
4022   const Handle(Graphic3d_Aspects)& anAspect = (!theHighlight.IsNull() && !theHighlight->BasicFillAreaAspect().IsNull())
4023                                             ?  (const Handle(Graphic3d_Aspects)& )theHighlight->BasicFillAreaAspect()
4024                                             :  theAspect->Aspect();
4025
4026   const bool toDistinguish = anAspect->Distinguish();
4027   const Graphic3d_MaterialAspect& aMatFrontSrc = anAspect->FrontMaterial();
4028   const Graphic3d_MaterialAspect& aMatBackSrc  = toDistinguish
4029                                                ? anAspect->BackMaterial()
4030                                                : aMatFrontSrc;
4031
4032   // handling transparency
4033   if (!theHighlight.IsNull()
4034     && theHighlight->BasicFillAreaAspect().IsNull())
4035   {
4036     theAlphaFront = theHighlight->ColorRGBA().Alpha();
4037     theAlphaBack  = theHighlight->ColorRGBA().Alpha();
4038   }
4039   else
4040   {
4041     theAlphaFront = aMatFrontSrc.Alpha();
4042     theAlphaBack  = aMatBackSrc .Alpha();
4043   }
4044
4045   if (anAspect->AlphaMode() == Graphic3d_AlphaMode_BlendAuto)
4046   {
4047     return theAlphaFront < 1.0f
4048         || theAlphaBack  < 1.0f;
4049   }
4050   return anAspect->AlphaMode() == Graphic3d_AlphaMode_Blend;
4051 }
4052
4053 // =======================================================================
4054 // function : SetColor4fv
4055 // purpose  :
4056 // =======================================================================
4057 void OpenGl_Context::SetColor4fv (const OpenGl_Vec4& theColor)
4058 {
4059   if (!myActiveProgram.IsNull())
4060   {
4061     if (const OpenGl_ShaderUniformLocation& aLoc = myActiveProgram->GetStateLocation (OpenGl_OCCT_COLOR))
4062     {
4063       myActiveProgram->SetUniform (this, aLoc, Vec4FromQuantityColor (theColor));
4064     }
4065   }
4066 #if !defined(GL_ES_VERSION_2_0)
4067   else if (core11 != NULL)
4068   {
4069     core11->glColor4fv (theColor.GetData());
4070   }
4071 #endif
4072 }
4073
4074 // =======================================================================
4075 // function : SetTypeOfLine
4076 // purpose  :
4077 // =======================================================================
4078 void OpenGl_Context::SetTypeOfLine (const Aspect_TypeOfLine  theType,
4079                                     const Standard_ShortReal theFactor)
4080 {
4081   SetLineStipple (theFactor, Graphic3d_Aspects::DefaultLinePatternForType (theType));
4082 }
4083
4084 // =======================================================================
4085 // function : SetLineStipple
4086 // purpose  :
4087 // =======================================================================
4088 void OpenGl_Context::SetLineStipple (const Standard_ShortReal theFactor,
4089                                      const uint16_t thePattern)
4090 {
4091   if (!myActiveProgram.IsNull())
4092   {
4093     if (const OpenGl_ShaderUniformLocation aPatternLoc = myActiveProgram->GetStateLocation (OpenGl_OCCT_LINE_STIPPLE_PATTERN))
4094     {
4095       if (hasGlslBitwiseOps != OpenGl_FeatureNotAvailable)
4096       {
4097         myActiveProgram->SetUniform (this, aPatternLoc, (Standard_Integer )thePattern);
4098       }
4099       else
4100       {
4101         Standard_Integer aPatArr[16] = {};
4102         for (unsigned int aBit = 0; aBit < 16; ++aBit)
4103         {
4104           aPatArr[aBit] = ((unsigned int)(thePattern) & (1U << aBit)) != 0 ? 1 : 0;
4105         }
4106         myActiveProgram->SetUniform (this, aPatternLoc, 16, aPatArr);
4107       }
4108       myActiveProgram->SetUniform (this, myActiveProgram->GetStateLocation (OpenGl_OCCT_LINE_STIPPLE_FACTOR), theFactor);
4109     }
4110     return;
4111   }
4112
4113 #if !defined(GL_ES_VERSION_2_0)
4114   if (thePattern != 0xFFFF)
4115   {
4116     if (core11 != NULL)
4117     {
4118       core11fwd->glEnable (GL_LINE_STIPPLE);
4119
4120       core11->glLineStipple (static_cast<GLint>    (theFactor),
4121                              static_cast<GLushort> (thePattern));
4122     }
4123   }
4124   else
4125   {
4126     if (core11 != NULL)
4127     {
4128       core11fwd->glDisable (GL_LINE_STIPPLE);
4129     }
4130   }
4131 #endif
4132 }
4133
4134 // =======================================================================
4135 // function : SetLineWidth
4136 // purpose  :
4137 // =======================================================================
4138 void OpenGl_Context::SetLineWidth (const Standard_ShortReal theWidth)
4139 {
4140   if (core11 != NULL)
4141   {
4142     // glLineWidth() is still defined within Core Profile, but has no effect with values != 1.0f
4143     core11fwd->glLineWidth (theWidth * myLineWidthScale);
4144   }
4145 }
4146
4147 // =======================================================================
4148 // function : SetTextureMatrix
4149 // purpose  :
4150 // =======================================================================
4151 void OpenGl_Context::SetTextureMatrix (const Handle(Graphic3d_TextureParams)& theParams,
4152                                        const Standard_Boolean theIsTopDown)
4153 {
4154   if (theParams.IsNull())
4155   {
4156     return;
4157   }
4158
4159   const Graphic3d_Vec2& aScale = theParams->Scale();
4160   const Graphic3d_Vec2& aTrans = theParams->Translation();
4161   if (!myActiveProgram.IsNull())
4162   {
4163     const GLint aUniLoc = myActiveProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_TRSF2D);
4164     if (aUniLoc == OpenGl_ShaderProgram::INVALID_LOCATION)
4165     {
4166       return;
4167     }
4168
4169     // pack transformation parameters
4170     OpenGl_Vec4 aTrsf[2] =
4171     {
4172       OpenGl_Vec4 (-aTrans.x(), -aTrans.y(), aScale.x(), aScale.y()),
4173       OpenGl_Vec4 (static_cast<float> (std::sin (-theParams->Rotation() * M_PI / 180.0)),
4174                    static_cast<float> (std::cos (-theParams->Rotation() * M_PI / 180.0)),
4175                    0.0f, 0.0f)
4176     };
4177     if (caps->isTopDownTextureUV != theIsTopDown)
4178     {
4179       // flip V
4180       aTrsf[0].y() = -aTrans.y() + 1.0f / aScale.y();
4181       aTrsf[0].w() = -aScale.y();
4182     }
4183     myActiveProgram->SetUniform (this, aUniLoc, 2, aTrsf);
4184     return;
4185   }
4186
4187 #if !defined(GL_ES_VERSION_2_0)
4188   if (core11 != NULL)
4189   {
4190     GLint aMatrixMode = GL_TEXTURE;
4191     ::glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
4192
4193     core11->glMatrixMode (GL_TEXTURE);
4194     OpenGl_Mat4 aTextureMat;
4195     if (caps->isTopDownTextureUV != theIsTopDown)
4196     {
4197       // flip V
4198       Graphic3d_TransformUtils::Scale     (aTextureMat,  aScale.x(), -aScale.y(), 1.0f);
4199       Graphic3d_TransformUtils::Translate (aTextureMat, -aTrans.x(), -aTrans.y() + 1.0f / aScale.y(), 0.0f);
4200     }
4201     else
4202     {
4203       Graphic3d_TransformUtils::Scale     (aTextureMat,  aScale.x(),  aScale.y(), 1.0f);
4204       Graphic3d_TransformUtils::Translate (aTextureMat, -aTrans.x(), -aTrans.y(), 0.0f);
4205     }
4206     Graphic3d_TransformUtils::Rotate (aTextureMat, -theParams->Rotation(), 0.0f, 0.0f, 1.0f);
4207     core11->glLoadMatrixf (aTextureMat);
4208     core11->glMatrixMode (aMatrixMode);
4209   }
4210 #endif
4211 }
4212
4213 // =======================================================================
4214 // function : SetPointSize
4215 // purpose  :
4216 // =======================================================================
4217 void OpenGl_Context::SetPointSize (const Standard_ShortReal theSize)
4218 {
4219   if (!myActiveProgram.IsNull())
4220   {
4221     myActiveProgram->SetUniform (this, myActiveProgram->GetStateLocation (OpenGl_OCCT_POINT_SIZE), theSize);
4222   #if !defined(GL_ES_VERSION_2_0)
4223     //myContext->core11fwd->glEnable (GL_VERTEX_PROGRAM_POINT_SIZE);
4224   #endif
4225   }
4226 #if !defined(GL_ES_VERSION_2_0)
4227   //else
4228   {
4229     core11fwd->glPointSize (theSize);
4230     if (core20fwd != NULL)
4231     {
4232       //myContext->core11fwd->glDisable (GL_VERTEX_PROGRAM_POINT_SIZE);
4233     }
4234   }
4235 #endif
4236 }
4237
4238 // =======================================================================
4239 // function : SetPointSpriteOrigin
4240 // purpose  :
4241 // =======================================================================
4242 void OpenGl_Context::SetPointSpriteOrigin()
4243 {
4244 #if !defined(GL_ES_VERSION_2_0)
4245   if (core15fwd == NULL)
4246   {
4247     return;
4248   }
4249
4250   const int aNewState = !myActiveProgram.IsNull() ? GL_UPPER_LEFT : GL_LOWER_LEFT;
4251   if (myPointSpriteOrig != aNewState)
4252   {
4253     myPointSpriteOrig = aNewState;
4254     core15fwd->glPointParameteri (GL_POINT_SPRITE_COORD_ORIGIN, aNewState);
4255   }
4256 #endif
4257 }
4258
4259 // =======================================================================
4260 // function : SetGlNormalizeEnabled
4261 // purpose  :
4262 // =======================================================================
4263 Standard_Boolean OpenGl_Context::SetGlNormalizeEnabled (Standard_Boolean isEnabled)
4264 {
4265   if (isEnabled == myIsGlNormalizeEnabled)
4266   {
4267     return myIsGlNormalizeEnabled;
4268   }
4269
4270   Standard_Boolean anOldGlNormalize = myIsGlNormalizeEnabled;
4271
4272   myIsGlNormalizeEnabled = isEnabled;
4273
4274 #if !defined(GL_ES_VERSION_2_0)
4275   if (core11 != NULL)
4276   {
4277     if (isEnabled)
4278     {
4279       ::glEnable  (GL_NORMALIZE);
4280     }
4281     else
4282     {
4283       ::glDisable (GL_NORMALIZE);
4284     }
4285   }
4286 #endif
4287
4288   return anOldGlNormalize;
4289 }
4290
4291 // =======================================================================
4292 // function : SetShadeModel
4293 // purpose  :
4294 // =======================================================================
4295 void OpenGl_Context::SetShadeModel (Graphic3d_TypeOfShadingModel theModel)
4296 {
4297 #if !defined(GL_ES_VERSION_2_0)
4298   if (core11 != NULL)
4299   {
4300     const Standard_Integer aModel = theModel == Graphic3d_TOSM_FACET
4301                                  || theModel == Graphic3d_TOSM_PBR_FACET ? GL_FLAT : GL_SMOOTH;
4302     if (myShadeModel == aModel)
4303     {
4304       return;
4305     }
4306     myShadeModel = aModel;
4307     core11->glShadeModel (aModel);
4308   }
4309 #else
4310   (void )theModel;
4311 #endif
4312 }
4313
4314 // =======================================================================
4315 // function : SetPolygonMode
4316 // purpose  :
4317 // =======================================================================
4318 Standard_Integer OpenGl_Context::SetPolygonMode (const Standard_Integer theMode)
4319 {
4320   if (myPolygonMode == theMode)
4321   {
4322     return myPolygonMode;
4323   }
4324
4325   const Standard_Integer anOldPolygonMode = myPolygonMode;
4326
4327   myPolygonMode = theMode;
4328
4329 #if !defined(GL_ES_VERSION_2_0)
4330   ::glPolygonMode (GL_FRONT_AND_BACK, (GLenum)theMode);
4331 #endif
4332
4333   return anOldPolygonMode;
4334 }
4335
4336 // =======================================================================
4337 // function : SetPolygonHatchEnabled
4338 // purpose  :
4339 // =======================================================================
4340 bool OpenGl_Context::SetPolygonHatchEnabled (const bool theIsEnabled)
4341 {
4342   if (myHatchStyles.IsNull())
4343   {
4344     return false;
4345   }
4346   else if (myHatchStyles->IsEnabled() == theIsEnabled)
4347   {
4348     return theIsEnabled;
4349   }
4350
4351   return myHatchStyles->SetEnabled (this, theIsEnabled);
4352 }
4353
4354 // =======================================================================
4355 // function : SetPolygonHatchStyle
4356 // purpose  :
4357 // =======================================================================
4358 Standard_Integer OpenGl_Context::SetPolygonHatchStyle (const Handle(Graphic3d_HatchStyle)& theStyle)
4359 {
4360   if (theStyle.IsNull())
4361   {
4362     return 0;
4363   }
4364
4365   if (myHatchStyles.IsNull())
4366   {
4367     if (!GetResource ("OpenGl_LineAttributes", myHatchStyles))
4368     {
4369       // share and register for release once the resource is no longer used
4370       myHatchStyles = new OpenGl_LineAttributes();
4371       ShareResource ("OpenGl_LineAttributes", myHatchStyles);
4372     }
4373   }
4374   if (myHatchStyles->TypeOfHatch() == theStyle->HatchType())
4375   {
4376     return theStyle->HatchType();
4377   }
4378
4379   return myHatchStyles->SetTypeOfHatch (this, theStyle);
4380 }
4381
4382 // =======================================================================
4383 // function : SetPolygonOffset
4384 // purpose  :
4385 // =======================================================================
4386 void OpenGl_Context::SetPolygonOffset (const Graphic3d_PolygonOffset& theOffset)
4387 {
4388   const bool toFillOld = (myPolygonOffset.Mode & Aspect_POM_Fill) == Aspect_POM_Fill;
4389   const bool toFillNew = (theOffset.Mode       & Aspect_POM_Fill) == Aspect_POM_Fill;
4390   if (toFillNew != toFillOld)
4391   {
4392     if (toFillNew)
4393     {
4394       glEnable (GL_POLYGON_OFFSET_FILL);
4395     }
4396     else
4397     {
4398       glDisable (GL_POLYGON_OFFSET_FILL);
4399     }
4400   }
4401
4402 #if !defined(GL_ES_VERSION_2_0)
4403   const bool toLineOld = (myPolygonOffset.Mode & Aspect_POM_Line) == Aspect_POM_Line;
4404   const bool toLineNew = (theOffset.Mode       & Aspect_POM_Line) == Aspect_POM_Line;
4405   if (toLineNew != toLineOld)
4406   {
4407     if (toLineNew)
4408     {
4409       glEnable (GL_POLYGON_OFFSET_LINE);
4410     }
4411     else
4412     {
4413       glDisable (GL_POLYGON_OFFSET_LINE);
4414     }
4415   }
4416
4417   const bool toPointOld = (myPolygonOffset.Mode & Aspect_POM_Point) == Aspect_POM_Point;
4418   const bool toPointNew = (theOffset.Mode       & Aspect_POM_Point) == Aspect_POM_Point;
4419   if (toPointNew != toPointOld)
4420   {
4421     if (toPointNew)
4422     {
4423       glEnable (GL_POLYGON_OFFSET_POINT);
4424     }
4425     else
4426     {
4427       glDisable (GL_POLYGON_OFFSET_POINT);
4428     }
4429   }
4430 #endif
4431
4432   if (myPolygonOffset.Factor != theOffset.Factor
4433    || myPolygonOffset.Units  != theOffset.Units)
4434   {
4435     glPolygonOffset (theOffset.Factor, theOffset.Units);
4436   }
4437   myPolygonOffset = theOffset;
4438 }
4439
4440 // =======================================================================
4441 // function : SetCamera
4442 // purpose  :
4443 // =======================================================================
4444 void OpenGl_Context::SetCamera (const Handle(Graphic3d_Camera)& theCamera)
4445 {
4446   myCamera = theCamera;
4447   if (!theCamera.IsNull())
4448   {
4449     ProjectionState.SetCurrent (theCamera->ProjectionMatrixF());
4450     WorldViewState .SetCurrent (theCamera->OrientationMatrixF());
4451     ApplyProjectionMatrix();
4452     ApplyWorldViewMatrix();
4453   }
4454 }
4455
4456 // =======================================================================
4457 // function : ApplyModelWorldMatrix
4458 // purpose  :
4459 // =======================================================================
4460 void OpenGl_Context::ApplyModelWorldMatrix()
4461 {
4462   if (myShaderManager->ModelWorldState().ModelWorldMatrix() != ModelWorldState.Current())
4463   {
4464     myShaderManager->UpdateModelWorldStateTo (ModelWorldState.Current());
4465   }
4466 }
4467
4468 // =======================================================================
4469 // function : ApplyWorldViewMatrix
4470 // purpose  :
4471 // =======================================================================
4472 void OpenGl_Context::ApplyWorldViewMatrix()
4473 {
4474   if (myShaderManager->ModelWorldState().ModelWorldMatrix() != THE_IDENTITY_MATRIX)
4475   {
4476     myShaderManager->UpdateModelWorldStateTo (THE_IDENTITY_MATRIX);
4477   }
4478   if (myShaderManager->WorldViewState().WorldViewMatrix() != WorldViewState.Current())
4479   {
4480     myShaderManager->UpdateWorldViewStateTo (WorldViewState.Current());
4481   }
4482 }
4483
4484 // =======================================================================
4485 // function : ApplyModelViewMatrix
4486 // purpose  :
4487 // =======================================================================
4488 void OpenGl_Context::ApplyModelViewMatrix()
4489 {
4490   if (myShaderManager->ModelWorldState().ModelWorldMatrix() != ModelWorldState.Current())
4491   {
4492     myShaderManager->UpdateModelWorldStateTo (ModelWorldState.Current());
4493   }
4494   if (myShaderManager->WorldViewState().WorldViewMatrix() != WorldViewState.Current())
4495   {
4496     myShaderManager->UpdateWorldViewStateTo  (WorldViewState.Current());
4497   }
4498 }
4499
4500 // =======================================================================
4501 // function : ApplyProjectionMatrix
4502 // purpose  :
4503 // =======================================================================
4504 void OpenGl_Context::ApplyProjectionMatrix()
4505 {
4506   if (myShaderManager->ProjectionState().ProjectionMatrix() != ProjectionState.Current())
4507   {
4508     myShaderManager->UpdateProjectionStateTo (ProjectionState.Current());
4509   }
4510 }
4511
4512 // =======================================================================
4513 // function : EnableFeatures
4514 // purpose  :
4515 // =======================================================================
4516 void OpenGl_Context::EnableFeatures() const
4517 {
4518   //
4519 }
4520
4521 // =======================================================================
4522 // function : DisableFeatures
4523 // purpose  :
4524 // =======================================================================
4525 void OpenGl_Context::DisableFeatures() const
4526 {
4527   // Disable stuff that's likely to slow down glDrawPixels.
4528   glDisable(GL_DITHER);
4529   glDisable(GL_BLEND);
4530   glDisable(GL_DEPTH_TEST);
4531   glDisable(GL_STENCIL_TEST);
4532
4533 #if !defined(GL_ES_VERSION_2_0)
4534   if (core11 == NULL)
4535   {
4536     return;
4537   }
4538
4539   glDisable(GL_TEXTURE_1D);
4540   glDisable(GL_TEXTURE_2D);
4541
4542   glDisable(GL_LIGHTING);
4543   glDisable(GL_ALPHA_TEST);
4544   glDisable(GL_FOG);
4545   glDisable(GL_LOGIC_OP);
4546
4547   glPixelTransferi(GL_MAP_COLOR, GL_FALSE);
4548   glPixelTransferi(GL_RED_SCALE, 1);
4549   glPixelTransferi(GL_RED_BIAS, 0);
4550   glPixelTransferi(GL_GREEN_SCALE, 1);
4551   glPixelTransferi(GL_GREEN_BIAS, 0);
4552   glPixelTransferi(GL_BLUE_SCALE, 1);
4553   glPixelTransferi(GL_BLUE_BIAS, 0);
4554   glPixelTransferi(GL_ALPHA_SCALE, 1);
4555   glPixelTransferi(GL_ALPHA_BIAS, 0);
4556
4557   if ((myGlVerMajor >= 1) && (myGlVerMinor >= 2))
4558   {
4559     if (CheckExtension ("GL_CONVOLUTION_1D_EXT"))
4560       glDisable(GL_CONVOLUTION_1D_EXT);
4561
4562     if (CheckExtension ("GL_CONVOLUTION_2D_EXT"))
4563       glDisable(GL_CONVOLUTION_2D_EXT);
4564
4565     if (CheckExtension ("GL_SEPARABLE_2D_EXT"))
4566       glDisable(GL_SEPARABLE_2D_EXT);
4567
4568     if (CheckExtension ("GL_SEPARABLE_2D_EXT"))
4569       glDisable(GL_HISTOGRAM_EXT);
4570
4571     if (CheckExtension ("GL_MINMAX_EXT"))
4572       glDisable(GL_MINMAX_EXT);
4573
4574     if (CheckExtension ("GL_TEXTURE_3D_EXT"))
4575       glDisable(GL_TEXTURE_3D_EXT);
4576   }
4577 #endif
4578 }
4579
4580 // =======================================================================
4581 // function : SetColorMask
4582 // purpose  :
4583 // =======================================================================
4584 bool OpenGl_Context::SetColorMask (bool theToWriteColor)
4585 {
4586   const GLboolean toWrite = theToWriteColor ? GL_TRUE : GL_FALSE;
4587   glColorMask (toWrite, toWrite, toWrite, toWrite);
4588
4589   const bool anOldValue = myColorMask;
4590   myColorMask = theToWriteColor;
4591   return anOldValue;
4592 }
4593
4594 // =======================================================================
4595 // function : SetSampleAlphaToCoverage
4596 // purpose  :
4597 // =======================================================================
4598 bool OpenGl_Context::SetSampleAlphaToCoverage (bool theToEnable)
4599 {
4600   bool toEnable = myAllowAlphaToCov && theToEnable;
4601   if (myAlphaToCoverage == toEnable)
4602   {
4603     return myAlphaToCoverage;
4604   }
4605
4606   if (core15fwd != NULL)
4607   {
4608     if (toEnable)
4609     {
4610       //core15fwd->core15fwd->glSampleCoverage (1.0f, GL_FALSE);
4611       core15fwd->glEnable (GL_SAMPLE_ALPHA_TO_COVERAGE);
4612     }
4613     else
4614     {
4615       core15fwd->glDisable (GL_SAMPLE_ALPHA_TO_COVERAGE);
4616     }
4617   }
4618
4619   const bool anOldValue = myAlphaToCoverage;
4620   myAlphaToCoverage = toEnable;
4621   return anOldValue;
4622 }
4623
4624 // =======================================================================
4625 // function : GetBufferSubData
4626 // purpose  :
4627 // =======================================================================
4628 bool OpenGl_Context::GetBufferSubData (GLenum theTarget, GLintptr theOffset, GLsizeiptr theSize, void* theData)
4629 {
4630   if (!hasGetBufferData)
4631   {
4632     return false;
4633   }
4634 #ifdef __EMSCRIPTEN__
4635   EM_ASM_(
4636   {
4637     Module.ctx.getBufferSubData($0, $1, HEAPU8.subarray($2, $2 + $3));
4638   }, theTarget, theOffset, theData, theSize);
4639   return true;
4640 #elif defined(GL_ES_VERSION_2_0)
4641   if (void* aData = core30fwd->glMapBufferRange (theTarget, theOffset, theSize, GL_MAP_READ_BIT))
4642   {
4643     memcpy (theData, aData, theSize);
4644     core30fwd->glUnmapBuffer (theTarget);
4645     return true;
4646   }
4647   return false;
4648 #else
4649   core15fwd->glGetBufferSubData (theTarget, theOffset, theSize, theData);
4650   return true;
4651 #endif
4652 }
4653
4654 // =======================================================================
4655 // function : DumpJson
4656 // purpose  :
4657 // =======================================================================
4658 void OpenGl_Context::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
4659 {
4660   OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
4661
4662   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myAnisoMax)
4663   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myTexClamp)
4664   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myMaxTexDim)
4665   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myMaxTexCombined)
4666   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myMaxDumpSizeX)
4667   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myMaxDumpSizeY)
4668   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myMaxClipPlanes)
4669   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myMaxMsaaSamples)
4670   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myMaxDrawBuffers)
4671   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myMaxColorAttachments)
4672   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myGlVerMajor)
4673   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myGlVerMinor)
4674   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIsInitialized)
4675   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIsStereoBuffers)
4676   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIsGlNormalizeEnabled)
4677
4678   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myHasRayTracing)
4679   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myHasRayTracingTextures)
4680   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myHasRayTracingAdaptiveSampling)
4681   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myHasRayTracingAdaptiveSamplingAtomic)
4682
4683   for (int i = 0; i < 4; i++)
4684   {
4685     OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myViewport[i])
4686   }
4687
4688   for (int i = 0; i < 4; i++)
4689   {
4690     OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myViewportVirt[i])
4691   }
4692
4693   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myPointSpriteOrig)
4694   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myRenderMode)
4695   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myPolygonMode)
4696   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myPolygonOffset)
4697   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myToCullBackFaces)
4698   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myReadBuffer)
4699
4700   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myDefaultVao)
4701   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myColorMask)
4702   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myAllowAlphaToCov)
4703   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myAlphaToCoverage)
4704   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIsGlDebugCtx)
4705
4706   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myResolution)
4707   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myResolutionRatio)
4708
4709   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myLineWidthScale)
4710   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myLineFeather)
4711   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myRenderScale)
4712   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myRenderScaleInv)
4713   
4714   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &ModelWorldState)
4715   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &WorldViewState)
4716   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &ProjectionState)
4717 }
4718
4719 // =======================================================================
4720 // function : DumpJsonOpenGlState
4721 // purpose  :
4722 // =======================================================================
4723 void OpenGl_Context::DumpJsonOpenGlState (Standard_OStream& theOStream, Standard_Integer)
4724 {
4725   GLboolean isEnableBlend = glIsEnabled (GL_BLEND);
4726   GLboolean isEnableCullFace = glIsEnabled (GL_CULL_FACE);
4727   GLboolean isEnableDepthTest = glIsEnabled (GL_DEPTH_TEST);
4728   
4729   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, isEnableBlend)
4730   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, isEnableCullFace)
4731   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, isEnableDepthTest)
4732 }
4733