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