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